Commit 93190ac1 authored by Justin Tee's avatar Justin Tee Committed by Martin K. Petersen

scsi: lpfc: Enhance congestion statistics collection

Various improvements are made for collecting congestion statistics:

 - Pre-existing logic is replaced with use of an hrtimer for increased
   reporting accuracy.

 - Congestion timestamp information is reorganized into a single struct.

 - Common statistic collection logic is refactored into a helper routine.
Signed-off-by: default avatarJustin Tee <justin.tee@broadcom.com>
Link: https://lore.kernel.org/r/20230523183206.7728-8-justintee8345@gmail.comSigned-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 6a84d015
...@@ -429,6 +429,15 @@ struct lpfc_cgn_param { ...@@ -429,6 +429,15 @@ struct lpfc_cgn_param {
/* Max number of days of congestion data */ /* Max number of days of congestion data */
#define LPFC_MAX_CGN_DAYS 10 #define LPFC_MAX_CGN_DAYS 10
struct lpfc_cgn_ts {
uint8_t month;
uint8_t day;
uint8_t year;
uint8_t hour;
uint8_t minute;
uint8_t second;
};
/* Format of congestion buffer info /* Format of congestion buffer info
* This structure defines memory thats allocated and registered with * This structure defines memory thats allocated and registered with
* the HBA firmware. When adding or removing fields from this structure * the HBA firmware. When adding or removing fields from this structure
...@@ -442,6 +451,7 @@ struct lpfc_cgn_info { ...@@ -442,6 +451,7 @@ struct lpfc_cgn_info {
#define LPFC_CGN_INFO_V1 1 #define LPFC_CGN_INFO_V1 1
#define LPFC_CGN_INFO_V2 2 #define LPFC_CGN_INFO_V2 2
#define LPFC_CGN_INFO_V3 3 #define LPFC_CGN_INFO_V3 3
#define LPFC_CGN_INFO_V4 4
uint8_t cgn_info_mode; /* 0=off 1=managed 2=monitor only */ uint8_t cgn_info_mode; /* 0=off 1=managed 2=monitor only */
uint8_t cgn_info_detect; uint8_t cgn_info_detect;
uint8_t cgn_info_action; uint8_t cgn_info_action;
...@@ -450,12 +460,7 @@ struct lpfc_cgn_info { ...@@ -450,12 +460,7 @@ struct lpfc_cgn_info {
uint8_t cgn_info_level2; uint8_t cgn_info_level2;
/* Start Time */ /* Start Time */
uint8_t cgn_info_month; struct lpfc_cgn_ts base_time;
uint8_t cgn_info_day;
uint8_t cgn_info_year;
uint8_t cgn_info_hour;
uint8_t cgn_info_minute;
uint8_t cgn_info_second;
/* minute / hours / daily indices */ /* minute / hours / daily indices */
uint8_t cgn_index_minute; uint8_t cgn_index_minute;
...@@ -496,45 +501,17 @@ struct lpfc_cgn_info { ...@@ -496,45 +501,17 @@ struct lpfc_cgn_info {
uint8_t cgn_stat_npm; /* Notifications per minute */ uint8_t cgn_stat_npm; /* Notifications per minute */
/* Start Time */ /* Start Time */
uint8_t cgn_stat_month; struct lpfc_cgn_ts stat_start; /* Base time */
uint8_t cgn_stat_day; uint8_t cgn_pad2;
uint8_t cgn_stat_year;
uint8_t cgn_stat_hour;
uint8_t cgn_stat_minute;
uint8_t cgn_pad2[2];
__le32 cgn_notification; __le32 cgn_notification;
__le32 cgn_peer_notification; __le32 cgn_peer_notification;
__le32 link_integ_notification; __le32 link_integ_notification;
__le32 delivery_notification; __le32 delivery_notification;
struct lpfc_cgn_ts stat_fpin; /* Last congestion notification FPIN */
uint8_t cgn_stat_cgn_month; /* Last congestion notification FPIN */ struct lpfc_cgn_ts stat_peer; /* Last peer congestion FPIN */
uint8_t cgn_stat_cgn_day; struct lpfc_cgn_ts stat_lnk; /* Last link integrity FPIN */
uint8_t cgn_stat_cgn_year; struct lpfc_cgn_ts stat_delivery; /* Last delivery notification FPIN */
uint8_t cgn_stat_cgn_hour;
uint8_t cgn_stat_cgn_min;
uint8_t cgn_stat_cgn_sec;
uint8_t cgn_stat_peer_month; /* Last peer congestion FPIN */
uint8_t cgn_stat_peer_day;
uint8_t cgn_stat_peer_year;
uint8_t cgn_stat_peer_hour;
uint8_t cgn_stat_peer_min;
uint8_t cgn_stat_peer_sec;
uint8_t cgn_stat_lnk_month; /* Last link integrity FPIN */
uint8_t cgn_stat_lnk_day;
uint8_t cgn_stat_lnk_year;
uint8_t cgn_stat_lnk_hour;
uint8_t cgn_stat_lnk_min;
uint8_t cgn_stat_lnk_sec;
uint8_t cgn_stat_del_month; /* Last delivery notification FPIN */
uint8_t cgn_stat_del_day;
uint8_t cgn_stat_del_year;
uint8_t cgn_stat_del_hour;
uint8_t cgn_stat_del_min;
uint8_t cgn_stat_del_sec;
); );
__le32 cgn_info_crc; __le32 cgn_info_crc;
...@@ -1043,8 +1020,6 @@ struct lpfc_hba { ...@@ -1043,8 +1020,6 @@ struct lpfc_hba {
* capability * capability
*/ */
#define HBA_FLOGI_ISSUED 0x100000 /* FLOGI was issued */ #define HBA_FLOGI_ISSUED 0x100000 /* FLOGI was issued */
#define HBA_SHORT_CMF 0x200000 /* shorter CMF timer routine */
#define HBA_CGN_DAY_WRAP 0x400000 /* HBA Congestion info day wraps */
#define HBA_DEFER_FLOGI 0x800000 /* Defer FLOGI till read_sparm cmpl */ #define HBA_DEFER_FLOGI 0x800000 /* Defer FLOGI till read_sparm cmpl */
#define HBA_SETUP 0x1000000 /* Signifies HBA setup is completed */ #define HBA_SETUP 0x1000000 /* Signifies HBA setup is completed */
#define HBA_NEEDS_CFG_PORT 0x2000000 /* SLI3 - needs a CONFIG_PORT mbox */ #define HBA_NEEDS_CFG_PORT 0x2000000 /* SLI3 - needs a CONFIG_PORT mbox */
...@@ -1527,6 +1502,7 @@ struct lpfc_hba { ...@@ -1527,6 +1502,7 @@ struct lpfc_hba {
uint64_t cmf_last_sync_bw; uint64_t cmf_last_sync_bw;
#define LPFC_CMF_BLK_SIZE 512 #define LPFC_CMF_BLK_SIZE 512
struct hrtimer cmf_timer; struct hrtimer cmf_timer;
struct hrtimer cmf_stats_timer; /* 1 minute stats timer */
atomic_t cmf_bw_wait; atomic_t cmf_bw_wait;
atomic_t cmf_busy; atomic_t cmf_busy;
atomic_t cmf_stop_io; /* To block request and stop IO's */ atomic_t cmf_stop_io; /* To block request and stop IO's */
...@@ -1574,12 +1550,11 @@ struct lpfc_hba { ...@@ -1574,12 +1550,11 @@ struct lpfc_hba {
atomic_t cgn_sync_alarm_cnt; /* Total alarm events for SYNC wqe */ atomic_t cgn_sync_alarm_cnt; /* Total alarm events for SYNC wqe */
atomic_t cgn_driver_evt_cnt; /* Total driver cgn events for fmw */ atomic_t cgn_driver_evt_cnt; /* Total driver cgn events for fmw */
atomic_t cgn_latency_evt_cnt; atomic_t cgn_latency_evt_cnt;
struct timespec64 cgn_daily_ts;
atomic64_t cgn_latency_evt; /* Avg latency per minute */ atomic64_t cgn_latency_evt; /* Avg latency per minute */
unsigned long cgn_evt_timestamp; unsigned long cgn_evt_timestamp;
#define LPFC_CGN_TIMER_TO_MIN 60000 /* ms in a minute */ #define LPFC_CGN_TIMER_TO_MIN 60000 /* ms in a minute */
uint32_t cgn_evt_minute; uint32_t cgn_evt_minute;
#define LPFC_SEC_MIN 60 #define LPFC_SEC_MIN 60UL
#define LPFC_MIN_HOUR 60 #define LPFC_MIN_HOUR 60
#define LPFC_HOUR_DAY 24 #define LPFC_HOUR_DAY 24
#define LPFC_MIN_DAY (LPFC_MIN_HOUR * LPFC_HOUR_DAY) #define LPFC_MIN_DAY (LPFC_MIN_HOUR * LPFC_HOUR_DAY)
......
...@@ -101,6 +101,7 @@ static struct scsi_transport_template *lpfc_vport_transport_template = NULL; ...@@ -101,6 +101,7 @@ static struct scsi_transport_template *lpfc_vport_transport_template = NULL;
static DEFINE_IDR(lpfc_hba_index); static DEFINE_IDR(lpfc_hba_index);
#define LPFC_NVMET_BUF_POST 254 #define LPFC_NVMET_BUF_POST 254
static int lpfc_vmid_res_alloc(struct lpfc_hba *phba, struct lpfc_vport *vport); static int lpfc_vmid_res_alloc(struct lpfc_hba *phba, struct lpfc_vport *vport);
static void lpfc_cgn_update_tstamp(struct lpfc_hba *phba, struct lpfc_cgn_ts *ts);
/** /**
* lpfc_config_port_prep - Perform lpfc initialization prior to config port * lpfc_config_port_prep - Perform lpfc initialization prior to config port
...@@ -3197,6 +3198,7 @@ lpfc_cmf_stop(struct lpfc_hba *phba) ...@@ -3197,6 +3198,7 @@ lpfc_cmf_stop(struct lpfc_hba *phba)
"6221 Stop CMF / Cancel Timer\n"); "6221 Stop CMF / Cancel Timer\n");
/* Cancel the CMF timer */ /* Cancel the CMF timer */
hrtimer_cancel(&phba->cmf_stats_timer);
hrtimer_cancel(&phba->cmf_timer); hrtimer_cancel(&phba->cmf_timer);
/* Zero CMF counters */ /* Zero CMF counters */
...@@ -3283,7 +3285,10 @@ lpfc_cmf_start(struct lpfc_hba *phba) ...@@ -3283,7 +3285,10 @@ lpfc_cmf_start(struct lpfc_hba *phba)
phba->cmf_timer_cnt = 0; phba->cmf_timer_cnt = 0;
hrtimer_start(&phba->cmf_timer, hrtimer_start(&phba->cmf_timer,
ktime_set(0, LPFC_CMF_INTERVAL * 1000000), ktime_set(0, LPFC_CMF_INTERVAL * NSEC_PER_MSEC),
HRTIMER_MODE_REL);
hrtimer_start(&phba->cmf_stats_timer,
ktime_set(0, LPFC_SEC_MIN * NSEC_PER_SEC),
HRTIMER_MODE_REL); HRTIMER_MODE_REL);
/* Setup for latency check in IO cmpl routines */ /* Setup for latency check in IO cmpl routines */
ktime_get_real_ts64(&phba->cmf_latency); ktime_get_real_ts64(&phba->cmf_latency);
...@@ -5595,81 +5600,74 @@ void ...@@ -5595,81 +5600,74 @@ void
lpfc_cgn_update_stat(struct lpfc_hba *phba, uint32_t dtag) lpfc_cgn_update_stat(struct lpfc_hba *phba, uint32_t dtag)
{ {
struct lpfc_cgn_info *cp; struct lpfc_cgn_info *cp;
struct tm broken;
struct timespec64 cur_time;
u32 cnt;
u32 value; u32 value;
/* Make sure we have a congestion info buffer */ /* Make sure we have a congestion info buffer */
if (!phba->cgn_i) if (!phba->cgn_i)
return; return;
cp = (struct lpfc_cgn_info *)phba->cgn_i->virt; cp = (struct lpfc_cgn_info *)phba->cgn_i->virt;
ktime_get_real_ts64(&cur_time);
time64_to_tm(cur_time.tv_sec, 0, &broken);
/* Update congestion statistics */ /* Update congestion statistics */
switch (dtag) { switch (dtag) {
case ELS_DTAG_LNK_INTEGRITY: case ELS_DTAG_LNK_INTEGRITY:
cnt = le32_to_cpu(cp->link_integ_notification); le32_add_cpu(&cp->link_integ_notification, 1);
cnt++; lpfc_cgn_update_tstamp(phba, &cp->stat_lnk);
cp->link_integ_notification = cpu_to_le32(cnt);
cp->cgn_stat_lnk_month = broken.tm_mon + 1;
cp->cgn_stat_lnk_day = broken.tm_mday;
cp->cgn_stat_lnk_year = broken.tm_year - 100;
cp->cgn_stat_lnk_hour = broken.tm_hour;
cp->cgn_stat_lnk_min = broken.tm_min;
cp->cgn_stat_lnk_sec = broken.tm_sec;
break; break;
case ELS_DTAG_DELIVERY: case ELS_DTAG_DELIVERY:
cnt = le32_to_cpu(cp->delivery_notification); le32_add_cpu(&cp->delivery_notification, 1);
cnt++; lpfc_cgn_update_tstamp(phba, &cp->stat_delivery);
cp->delivery_notification = cpu_to_le32(cnt);
cp->cgn_stat_del_month = broken.tm_mon + 1;
cp->cgn_stat_del_day = broken.tm_mday;
cp->cgn_stat_del_year = broken.tm_year - 100;
cp->cgn_stat_del_hour = broken.tm_hour;
cp->cgn_stat_del_min = broken.tm_min;
cp->cgn_stat_del_sec = broken.tm_sec;
break; break;
case ELS_DTAG_PEER_CONGEST: case ELS_DTAG_PEER_CONGEST:
cnt = le32_to_cpu(cp->cgn_peer_notification); le32_add_cpu(&cp->cgn_peer_notification, 1);
cnt++; lpfc_cgn_update_tstamp(phba, &cp->stat_peer);
cp->cgn_peer_notification = cpu_to_le32(cnt);
cp->cgn_stat_peer_month = broken.tm_mon + 1;
cp->cgn_stat_peer_day = broken.tm_mday;
cp->cgn_stat_peer_year = broken.tm_year - 100;
cp->cgn_stat_peer_hour = broken.tm_hour;
cp->cgn_stat_peer_min = broken.tm_min;
cp->cgn_stat_peer_sec = broken.tm_sec;
break; break;
case ELS_DTAG_CONGESTION: case ELS_DTAG_CONGESTION:
cnt = le32_to_cpu(cp->cgn_notification); le32_add_cpu(&cp->cgn_notification, 1);
cnt++; lpfc_cgn_update_tstamp(phba, &cp->stat_fpin);
cp->cgn_notification = cpu_to_le32(cnt);
cp->cgn_stat_cgn_month = broken.tm_mon + 1;
cp->cgn_stat_cgn_day = broken.tm_mday;
cp->cgn_stat_cgn_year = broken.tm_year - 100;
cp->cgn_stat_cgn_hour = broken.tm_hour;
cp->cgn_stat_cgn_min = broken.tm_min;
cp->cgn_stat_cgn_sec = broken.tm_sec;
} }
if (phba->cgn_fpin_frequency && if (phba->cgn_fpin_frequency &&
phba->cgn_fpin_frequency != LPFC_FPIN_INIT_FREQ) { phba->cgn_fpin_frequency != LPFC_FPIN_INIT_FREQ) {
value = LPFC_CGN_TIMER_TO_MIN / phba->cgn_fpin_frequency; value = LPFC_CGN_TIMER_TO_MIN / phba->cgn_fpin_frequency;
cp->cgn_stat_npm = value; cp->cgn_stat_npm = value;
} }
value = lpfc_cgn_calc_crc32(cp, LPFC_CGN_INFO_SZ, value = lpfc_cgn_calc_crc32(cp, LPFC_CGN_INFO_SZ,
LPFC_CGN_CRC32_SEED); LPFC_CGN_CRC32_SEED);
cp->cgn_info_crc = cpu_to_le32(value); cp->cgn_info_crc = cpu_to_le32(value);
} }
/** /**
* lpfc_cgn_save_evt_cnt - Save data into registered congestion buffer * lpfc_cgn_update_tstamp - Update cmf timestamp
* @phba: pointer to lpfc hba data structure. * @phba: pointer to lpfc hba data structure.
* @ts: structure to write the timestamp to.
*/
void
lpfc_cgn_update_tstamp(struct lpfc_hba *phba, struct lpfc_cgn_ts *ts)
{
struct timespec64 cur_time;
struct tm tm_val;
ktime_get_real_ts64(&cur_time);
time64_to_tm(cur_time.tv_sec, 0, &tm_val);
ts->month = tm_val.tm_mon + 1;
ts->day = tm_val.tm_mday;
ts->year = tm_val.tm_year - 100;
ts->hour = tm_val.tm_hour;
ts->minute = tm_val.tm_min;
ts->second = tm_val.tm_sec;
lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT,
"2646 Updated CMF timestamp : "
"%u/%u/%u %u:%u:%u\n",
ts->day, ts->month,
ts->year, ts->hour,
ts->minute, ts->second);
}
/**
* lpfc_cmf_stats_timer - Save data into registered congestion buffer
* @timer: Timer cookie to access lpfc private data
* *
* Save the congestion event data every minute. * Save the congestion event data every minute.
* On the hour collapse all the minute data into hour data. Every day * On the hour collapse all the minute data into hour data. Every day
...@@ -5677,12 +5675,11 @@ lpfc_cgn_update_stat(struct lpfc_hba *phba, uint32_t dtag) ...@@ -5677,12 +5675,11 @@ lpfc_cgn_update_stat(struct lpfc_hba *phba, uint32_t dtag)
* and fabrc congestion event counters that will be saved out * and fabrc congestion event counters that will be saved out
* to the registered congestion buffer every minute. * to the registered congestion buffer every minute.
*/ */
static void static enum hrtimer_restart
lpfc_cgn_save_evt_cnt(struct lpfc_hba *phba) lpfc_cmf_stats_timer(struct hrtimer *timer)
{ {
struct lpfc_hba *phba;
struct lpfc_cgn_info *cp; struct lpfc_cgn_info *cp;
struct tm broken;
struct timespec64 cur_time;
uint32_t i, index; uint32_t i, index;
uint16_t value, mvalue; uint16_t value, mvalue;
uint64_t bps; uint64_t bps;
...@@ -5693,21 +5690,18 @@ lpfc_cgn_save_evt_cnt(struct lpfc_hba *phba) ...@@ -5693,21 +5690,18 @@ lpfc_cgn_save_evt_cnt(struct lpfc_hba *phba)
__le32 *lptr; __le32 *lptr;
__le16 *mptr; __le16 *mptr;
phba = container_of(timer, struct lpfc_hba, cmf_stats_timer);
/* Make sure we have a congestion info buffer */ /* Make sure we have a congestion info buffer */
if (!phba->cgn_i) if (!phba->cgn_i)
return; return HRTIMER_NORESTART;
cp = (struct lpfc_cgn_info *)phba->cgn_i->virt; cp = (struct lpfc_cgn_info *)phba->cgn_i->virt;
if (time_before(jiffies, phba->cgn_evt_timestamp))
return;
phba->cgn_evt_timestamp = jiffies + phba->cgn_evt_timestamp = jiffies +
msecs_to_jiffies(LPFC_CGN_TIMER_TO_MIN); msecs_to_jiffies(LPFC_CGN_TIMER_TO_MIN);
phba->cgn_evt_minute++; phba->cgn_evt_minute++;
/* We should get to this point in the routine on 1 minute intervals */ /* We should get to this point in the routine on 1 minute intervals */
lpfc_cgn_update_tstamp(phba, &cp->base_time);
ktime_get_real_ts64(&cur_time);
time64_to_tm(cur_time.tv_sec, 0, &broken);
if (phba->cgn_fpin_frequency && if (phba->cgn_fpin_frequency &&
phba->cgn_fpin_frequency != LPFC_FPIN_INIT_FREQ) { phba->cgn_fpin_frequency != LPFC_FPIN_INIT_FREQ) {
...@@ -5860,31 +5854,6 @@ lpfc_cgn_save_evt_cnt(struct lpfc_hba *phba) ...@@ -5860,31 +5854,6 @@ lpfc_cgn_save_evt_cnt(struct lpfc_hba *phba)
index = 0; index = 0;
} }
/* Anytime we overwrite daily index 0, after we wrap,
* we will be overwriting the oldest day, so we must
* update the congestion data start time for that day.
* That start time should have previously been saved after
* we wrote the last days worth of data.
*/
if ((phba->hba_flag & HBA_CGN_DAY_WRAP) && index == 0) {
time64_to_tm(phba->cgn_daily_ts.tv_sec, 0, &broken);
cp->cgn_info_month = broken.tm_mon + 1;
cp->cgn_info_day = broken.tm_mday;
cp->cgn_info_year = broken.tm_year - 100;
cp->cgn_info_hour = broken.tm_hour;
cp->cgn_info_minute = broken.tm_min;
cp->cgn_info_second = broken.tm_sec;
lpfc_printf_log
(phba, KERN_INFO, LOG_CGN_MGMT,
"2646 CGNInfo idx0 Start Time: "
"%d/%d/%d %d:%d:%d\n",
cp->cgn_info_day, cp->cgn_info_month,
cp->cgn_info_year, cp->cgn_info_hour,
cp->cgn_info_minute, cp->cgn_info_second);
}
dvalue = 0; dvalue = 0;
wvalue = 0; wvalue = 0;
lvalue = 0; lvalue = 0;
...@@ -5918,15 +5887,6 @@ lpfc_cgn_save_evt_cnt(struct lpfc_hba *phba) ...@@ -5918,15 +5887,6 @@ lpfc_cgn_save_evt_cnt(struct lpfc_hba *phba)
"2420 Congestion Info - daily (%d): " "2420 Congestion Info - daily (%d): "
"%d %d %d %d %d\n", "%d %d %d %d %d\n",
index, dvalue, wvalue, lvalue, mvalue, avalue); index, dvalue, wvalue, lvalue, mvalue, avalue);
/* We just wrote LPFC_MAX_CGN_DAYS of data,
* so we are wrapped on any data after this.
* Save this as the start time for the next day.
*/
if (index == (LPFC_MAX_CGN_DAYS - 1)) {
phba->hba_flag |= HBA_CGN_DAY_WRAP;
ktime_get_real_ts64(&phba->cgn_daily_ts);
}
} }
/* Use the frequency found in the last rcv'ed FPIN */ /* Use the frequency found in the last rcv'ed FPIN */
...@@ -5937,6 +5897,10 @@ lpfc_cgn_save_evt_cnt(struct lpfc_hba *phba) ...@@ -5937,6 +5897,10 @@ lpfc_cgn_save_evt_cnt(struct lpfc_hba *phba)
lvalue = lpfc_cgn_calc_crc32(cp, LPFC_CGN_INFO_SZ, lvalue = lpfc_cgn_calc_crc32(cp, LPFC_CGN_INFO_SZ,
LPFC_CGN_CRC32_SEED); LPFC_CGN_CRC32_SEED);
cp->cgn_info_crc = cpu_to_le32(lvalue); cp->cgn_info_crc = cpu_to_le32(lvalue);
hrtimer_forward_now(timer, ktime_set(0, LPFC_SEC_MIN * NSEC_PER_SEC));
return HRTIMER_RESTART;
} }
/** /**
...@@ -6067,13 +6031,6 @@ lpfc_cmf_timer(struct hrtimer *timer) ...@@ -6067,13 +6031,6 @@ lpfc_cmf_timer(struct hrtimer *timer)
if (ms && ms < LPFC_CMF_INTERVAL) { if (ms && ms < LPFC_CMF_INTERVAL) {
cnt = div_u64(total, ms); /* bytes per ms */ cnt = div_u64(total, ms); /* bytes per ms */
cnt *= LPFC_CMF_INTERVAL; /* what total should be */ cnt *= LPFC_CMF_INTERVAL; /* what total should be */
/* If the timeout is scheduled to be shorter,
* this value may skew the data, so cap it at mbpi.
*/
if ((phba->hba_flag & HBA_SHORT_CMF) && cnt > mbpi)
cnt = mbpi;
extra = cnt - total; extra = cnt - total;
} }
lpfc_issue_cmf_sync_wqe(phba, LPFC_CMF_INTERVAL, total + extra); lpfc_issue_cmf_sync_wqe(phba, LPFC_CMF_INTERVAL, total + extra);
...@@ -6143,34 +6100,6 @@ lpfc_cmf_timer(struct hrtimer *timer) ...@@ -6143,34 +6100,6 @@ lpfc_cmf_timer(struct hrtimer *timer)
} }
phba->rx_block_cnt += div_u64(rcv, 512); /* save 512 byte block cnt */ phba->rx_block_cnt += div_u64(rcv, 512); /* save 512 byte block cnt */
/* Each minute save Fabric and Driver congestion information */
lpfc_cgn_save_evt_cnt(phba);
phba->hba_flag &= ~HBA_SHORT_CMF;
/* Since we need to call lpfc_cgn_save_evt_cnt every minute, on the
* minute, adjust our next timer interval, if needed, to ensure a
* 1 minute granularity when we get the next timer interrupt.
*/
if (time_after(jiffies + msecs_to_jiffies(LPFC_CMF_INTERVAL),
phba->cgn_evt_timestamp)) {
timer_interval = jiffies_to_msecs(phba->cgn_evt_timestamp -
jiffies);
if (timer_interval <= 0)
timer_interval = LPFC_CMF_INTERVAL;
else
phba->hba_flag |= HBA_SHORT_CMF;
/* If we adjust timer_interval, max_bytes_per_interval
* needs to be adjusted as well.
*/
phba->cmf_link_byte_count = div_u64(phba->cmf_max_line_rate *
timer_interval, 1000);
if (phba->cmf_active_mode == LPFC_CFG_MONITOR)
phba->cmf_max_bytes_per_interval =
phba->cmf_link_byte_count;
}
/* Since total_bytes has already been zero'ed, its okay to unblock /* Since total_bytes has already been zero'ed, its okay to unblock
* after max_bytes_per_interval is setup. * after max_bytes_per_interval is setup.
*/ */
...@@ -8016,6 +7945,9 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba) ...@@ -8016,6 +7945,9 @@ lpfc_sli4_driver_resource_setup(struct lpfc_hba *phba)
/* CMF congestion timer */ /* CMF congestion timer */
hrtimer_init(&phba->cmf_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); hrtimer_init(&phba->cmf_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
phba->cmf_timer.function = lpfc_cmf_timer; phba->cmf_timer.function = lpfc_cmf_timer;
/* CMF 1 minute stats collection timer */
hrtimer_init(&phba->cmf_stats_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
phba->cmf_stats_timer.function = lpfc_cmf_stats_timer;
/* /*
* Control structure for handling external multi-buffer mailbox * Control structure for handling external multi-buffer mailbox
...@@ -13525,6 +13457,7 @@ lpfc_sli4_hba_unset(struct lpfc_hba *phba) ...@@ -13525,6 +13457,7 @@ lpfc_sli4_hba_unset(struct lpfc_hba *phba)
struct pci_dev *pdev = phba->pcidev; struct pci_dev *pdev = phba->pcidev;
lpfc_stop_hba_timers(phba); lpfc_stop_hba_timers(phba);
hrtimer_cancel(&phba->cmf_stats_timer);
hrtimer_cancel(&phba->cmf_timer); hrtimer_cancel(&phba->cmf_timer);
if (phba->pport) if (phba->pport)
...@@ -13649,8 +13582,6 @@ void ...@@ -13649,8 +13582,6 @@ void
lpfc_init_congestion_buf(struct lpfc_hba *phba) lpfc_init_congestion_buf(struct lpfc_hba *phba)
{ {
struct lpfc_cgn_info *cp; struct lpfc_cgn_info *cp;
struct timespec64 cmpl_time;
struct tm broken;
uint16_t size; uint16_t size;
uint32_t crc; uint32_t crc;
...@@ -13670,11 +13601,10 @@ lpfc_init_congestion_buf(struct lpfc_hba *phba) ...@@ -13670,11 +13601,10 @@ lpfc_init_congestion_buf(struct lpfc_hba *phba)
atomic_set(&phba->cgn_latency_evt_cnt, 0); atomic_set(&phba->cgn_latency_evt_cnt, 0);
atomic64_set(&phba->cgn_latency_evt, 0); atomic64_set(&phba->cgn_latency_evt, 0);
phba->cgn_evt_minute = 0; phba->cgn_evt_minute = 0;
phba->hba_flag &= ~HBA_CGN_DAY_WRAP;
memset(cp, 0xff, offsetof(struct lpfc_cgn_info, cgn_stat)); memset(cp, 0xff, offsetof(struct lpfc_cgn_info, cgn_stat));
cp->cgn_info_size = cpu_to_le16(LPFC_CGN_INFO_SZ); cp->cgn_info_size = cpu_to_le16(LPFC_CGN_INFO_SZ);
cp->cgn_info_version = LPFC_CGN_INFO_V3; cp->cgn_info_version = LPFC_CGN_INFO_V4;
/* cgn parameters */ /* cgn parameters */
cp->cgn_info_mode = phba->cgn_p.cgn_param_mode; cp->cgn_info_mode = phba->cgn_p.cgn_param_mode;
...@@ -13682,22 +13612,7 @@ lpfc_init_congestion_buf(struct lpfc_hba *phba) ...@@ -13682,22 +13612,7 @@ lpfc_init_congestion_buf(struct lpfc_hba *phba)
cp->cgn_info_level1 = phba->cgn_p.cgn_param_level1; cp->cgn_info_level1 = phba->cgn_p.cgn_param_level1;
cp->cgn_info_level2 = phba->cgn_p.cgn_param_level2; cp->cgn_info_level2 = phba->cgn_p.cgn_param_level2;
ktime_get_real_ts64(&cmpl_time); lpfc_cgn_update_tstamp(phba, &cp->base_time);
time64_to_tm(cmpl_time.tv_sec, 0, &broken);
cp->cgn_info_month = broken.tm_mon + 1;
cp->cgn_info_day = broken.tm_mday;
cp->cgn_info_year = broken.tm_year - 100; /* relative to 2000 */
cp->cgn_info_hour = broken.tm_hour;
cp->cgn_info_minute = broken.tm_min;
cp->cgn_info_second = broken.tm_sec;
lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT | LOG_INIT,
"2643 CGNInfo Init: Start Time "
"%d/%d/%d %d:%d:%d\n",
cp->cgn_info_day, cp->cgn_info_month,
cp->cgn_info_year, cp->cgn_info_hour,
cp->cgn_info_minute, cp->cgn_info_second);
/* Fill in default LUN qdepth */ /* Fill in default LUN qdepth */
if (phba->pport) { if (phba->pport) {
...@@ -13720,8 +13635,6 @@ void ...@@ -13720,8 +13635,6 @@ void
lpfc_init_congestion_stat(struct lpfc_hba *phba) lpfc_init_congestion_stat(struct lpfc_hba *phba)
{ {
struct lpfc_cgn_info *cp; struct lpfc_cgn_info *cp;
struct timespec64 cmpl_time;
struct tm broken;
uint32_t crc; uint32_t crc;
lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT, lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT,
...@@ -13733,22 +13646,7 @@ lpfc_init_congestion_stat(struct lpfc_hba *phba) ...@@ -13733,22 +13646,7 @@ lpfc_init_congestion_stat(struct lpfc_hba *phba)
cp = (struct lpfc_cgn_info *)phba->cgn_i->virt; cp = (struct lpfc_cgn_info *)phba->cgn_i->virt;
memset(&cp->cgn_stat, 0, sizeof(cp->cgn_stat)); memset(&cp->cgn_stat, 0, sizeof(cp->cgn_stat));
ktime_get_real_ts64(&cmpl_time); lpfc_cgn_update_tstamp(phba, &cp->stat_start);
time64_to_tm(cmpl_time.tv_sec, 0, &broken);
cp->cgn_stat_month = broken.tm_mon + 1;
cp->cgn_stat_day = broken.tm_mday;
cp->cgn_stat_year = broken.tm_year - 100; /* relative to 2000 */
cp->cgn_stat_hour = broken.tm_hour;
cp->cgn_stat_minute = broken.tm_min;
lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT | LOG_INIT,
"2647 CGNstat Init: Start Time "
"%d/%d/%d %d:%d\n",
cp->cgn_stat_day, cp->cgn_stat_month,
cp->cgn_stat_year, cp->cgn_stat_hour,
cp->cgn_stat_minute);
crc = lpfc_cgn_calc_crc32(cp, LPFC_CGN_INFO_SZ, LPFC_CGN_CRC32_SEED); crc = lpfc_cgn_calc_crc32(cp, LPFC_CGN_INFO_SZ, LPFC_CGN_CRC32_SEED);
cp->cgn_info_crc = cpu_to_le32(crc); cp->cgn_info_crc = cpu_to_le32(crc);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment