Skip to content

Commit 8c42a65

Browse files
jsmart-ghmartinkpetersen
authored andcommitted
scsi: lpfc: Add cm statistics buffer support
The cmf framework requires the driver to maintain a cm statistics table, accessible inband, of congestion related statistics that are reported per minute, rolled up to per hour, and rolled up again per day. Several days worth may be maintained. The table is registered with the adapter when the MIB feature is enabled. Add definition of the table and add support to register the table with the adapter. Includes definition and initialization of event counters that are later added to the statistics table. Link: https://lore.kernel.org/r/[email protected] Co-developed-by: Justin Tee <[email protected]> Signed-off-by: Justin Tee <[email protected]> Signed-off-by: James Smart <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]>
1 parent 9064aeb commit 8c42a65

File tree

5 files changed

+272
-0
lines changed

5 files changed

+272
-0
lines changed

drivers/scsi/lpfc/lpfc.h

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,127 @@ struct lpfc_trunk_link {
403403
link3;
404404
};
405405

406+
/* Max number of days of congestion data */
407+
#define LPFC_MAX_CGN_DAYS 10
408+
409+
/* Format of congestion buffer info
410+
* This structure defines memory thats allocated and registered with
411+
* the HBA firmware. When adding or removing fields from this structure
412+
* the alignment must match the HBA firmware.
413+
*/
414+
415+
struct lpfc_cgn_info {
416+
/* Header */
417+
__le16 cgn_info_size; /* is sizeof(struct lpfc_cgn_info) */
418+
uint8_t cgn_info_version; /* represents format of structure */
419+
#define LPFC_CGN_INFO_V1 1
420+
#define LPFC_CGN_INFO_V2 2
421+
#define LPFC_CGN_INFO_V3 3
422+
uint8_t cgn_info_mode; /* 0=off 1=managed 2=monitor only */
423+
uint8_t cgn_info_detect;
424+
uint8_t cgn_info_action;
425+
uint8_t cgn_info_level0;
426+
uint8_t cgn_info_level1;
427+
uint8_t cgn_info_level2;
428+
429+
/* Start Time */
430+
uint8_t cgn_info_month;
431+
uint8_t cgn_info_day;
432+
uint8_t cgn_info_year;
433+
uint8_t cgn_info_hour;
434+
uint8_t cgn_info_minute;
435+
uint8_t cgn_info_second;
436+
437+
/* minute / hours / daily indices */
438+
uint8_t cgn_index_minute;
439+
uint8_t cgn_index_hour;
440+
uint8_t cgn_index_day;
441+
442+
__le16 cgn_warn_freq;
443+
__le16 cgn_alarm_freq;
444+
__le16 cgn_lunq;
445+
uint8_t cgn_pad1[8];
446+
447+
/* Driver Information */
448+
__le16 cgn_drvr_min[60];
449+
__le32 cgn_drvr_hr[24];
450+
__le32 cgn_drvr_day[LPFC_MAX_CGN_DAYS];
451+
452+
/* Congestion Warnings */
453+
__le16 cgn_warn_min[60];
454+
__le32 cgn_warn_hr[24];
455+
__le32 cgn_warn_day[LPFC_MAX_CGN_DAYS];
456+
457+
/* Latency Information */
458+
__le32 cgn_latency_min[60];
459+
__le32 cgn_latency_hr[24];
460+
__le32 cgn_latency_day[LPFC_MAX_CGN_DAYS];
461+
462+
/* Bandwidth Information */
463+
__le16 cgn_bw_min[60];
464+
__le16 cgn_bw_hr[24];
465+
__le16 cgn_bw_day[LPFC_MAX_CGN_DAYS];
466+
467+
/* Congestion Alarms */
468+
__le16 cgn_alarm_min[60];
469+
__le32 cgn_alarm_hr[24];
470+
__le32 cgn_alarm_day[LPFC_MAX_CGN_DAYS];
471+
472+
/* Start of congestion statistics */
473+
uint8_t cgn_stat_npm; /* Notifications per minute */
474+
475+
/* Start Time */
476+
uint8_t cgn_stat_month;
477+
uint8_t cgn_stat_day;
478+
uint8_t cgn_stat_year;
479+
uint8_t cgn_stat_hour;
480+
uint8_t cgn_stat_minute;
481+
uint8_t cgn_pad2[2];
482+
483+
__le32 cgn_notification;
484+
__le32 cgn_peer_notification;
485+
__le32 link_integ_notification;
486+
__le32 delivery_notification;
487+
488+
uint8_t cgn_stat_cgn_month; /* Last congestion notification FPIN */
489+
uint8_t cgn_stat_cgn_day;
490+
uint8_t cgn_stat_cgn_year;
491+
uint8_t cgn_stat_cgn_hour;
492+
uint8_t cgn_stat_cgn_min;
493+
uint8_t cgn_stat_cgn_sec;
494+
495+
uint8_t cgn_stat_peer_month; /* Last peer congestion FPIN */
496+
uint8_t cgn_stat_peer_day;
497+
uint8_t cgn_stat_peer_year;
498+
uint8_t cgn_stat_peer_hour;
499+
uint8_t cgn_stat_peer_min;
500+
uint8_t cgn_stat_peer_sec;
501+
502+
uint8_t cgn_stat_lnk_month; /* Last link integrity FPIN */
503+
uint8_t cgn_stat_lnk_day;
504+
uint8_t cgn_stat_lnk_year;
505+
uint8_t cgn_stat_lnk_hour;
506+
uint8_t cgn_stat_lnk_min;
507+
uint8_t cgn_stat_lnk_sec;
508+
509+
uint8_t cgn_stat_del_month; /* Last delivery notification FPIN */
510+
uint8_t cgn_stat_del_day;
511+
uint8_t cgn_stat_del_year;
512+
uint8_t cgn_stat_del_hour;
513+
uint8_t cgn_stat_del_min;
514+
uint8_t cgn_stat_del_sec;
515+
#define LPFC_CGN_STAT_SIZE 48
516+
#define LPFC_CGN_DATA_SIZE (sizeof(struct lpfc_cgn_info) - \
517+
LPFC_CGN_STAT_SIZE - sizeof(uint32_t))
518+
519+
__le32 cgn_info_crc;
520+
#define LPFC_CGN_CRC32_MAGIC_NUMBER 0x1EDC6F41
521+
#define LPFC_CGN_CRC32_SEED 0xFFFFFFFF
522+
};
523+
524+
#define LPFC_CGN_INFO_SZ (sizeof(struct lpfc_cgn_info) - \
525+
sizeof(uint32_t))
526+
406527
struct lpfc_cgn_acqe_stat {
407528
atomic64_t alarm;
408529
atomic64_t warn;
@@ -1374,10 +1495,22 @@ struct lpfc_hba {
13741495
struct lpfc_cgn_acqe_stat cgn_acqe_stat;
13751496

13761497
/* Congestion buffer information */
1498+
struct lpfc_dmabuf *cgn_i; /* Congestion Info buffer */
13771499
atomic_t cgn_fabric_warn_cnt; /* Total warning cgn events for info */
13781500
atomic_t cgn_fabric_alarm_cnt; /* Total alarm cgn events for info */
13791501
atomic_t cgn_sync_warn_cnt; /* Total warning events for SYNC wqe */
13801502
atomic_t cgn_sync_alarm_cnt; /* Total alarm events for SYNC wqe */
1503+
atomic_t cgn_driver_evt_cnt; /* Total driver cgn events for fmw */
1504+
atomic_t cgn_latency_evt_cnt;
1505+
struct timespec64 cgn_daily_ts;
1506+
atomic64_t cgn_latency_evt; /* Avg latency per minute */
1507+
unsigned long cgn_evt_timestamp;
1508+
#define LPFC_CGN_TIMER_TO_MIN 60000 /* ms in a minute */
1509+
uint32_t cgn_evt_minute;
1510+
#define LPFC_SEC_MIN 60
1511+
#define LPFC_MIN_HOUR 60
1512+
#define LPFC_HOUR_DAY 24
1513+
#define LPFC_MIN_DAY (LPFC_MIN_HOUR * LPFC_HOUR_DAY)
13811514

13821515
struct hlist_node cpuhp; /* used for cpuhp per hba callback */
13831516
struct timer_list cpuhp_poll_timer;

drivers/scsi/lpfc/lpfc_crtn.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ void lpfc_request_features(struct lpfc_hba *, struct lpfcMboxq *);
5858
int lpfc_sli4_mbox_rsrc_extent(struct lpfc_hba *, struct lpfcMboxq *,
5959
uint16_t, uint16_t, bool);
6060
int lpfc_get_sli4_parameters(struct lpfc_hba *, LPFC_MBOXQ_t *);
61+
int lpfc_reg_congestion_buf(struct lpfc_hba *phba);
6162
struct lpfc_vport *lpfc_find_vport_by_did(struct lpfc_hba *, uint32_t);
6263
void lpfc_cleanup_rcv_buffers(struct lpfc_vport *);
6364
void lpfc_rcv_seq_check_edtov(struct lpfc_vport *);
@@ -74,6 +75,8 @@ int lpfc_init_iocb_list(struct lpfc_hba *phba, int cnt);
7475
void lpfc_free_iocb_list(struct lpfc_hba *phba);
7576
int lpfc_post_rq_buffer(struct lpfc_hba *phba, struct lpfc_queue *hrq,
7677
struct lpfc_queue *drq, int count, int idx);
78+
void lpfc_init_congestion_stat(struct lpfc_hba *phba);
79+
void lpfc_init_congestion_buf(struct lpfc_hba *phba);
7780
int lpfc_config_cgn_signal(struct lpfc_hba *phba);
7881

7982
void lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *, LPFC_MBOXQ_t *);

drivers/scsi/lpfc/lpfc_hw4.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1025,6 +1025,7 @@ struct mbox_header {
10251025
#define LPFC_MBOX_OPCODE_SET_HOST_DATA 0x5D
10261026
#define LPFC_MBOX_OPCODE_SEND_ACTIVATION 0x73
10271027
#define LPFC_MBOX_OPCODE_RESET_LICENSES 0x74
1028+
#define LPFC_MBOX_OPCODE_REG_CONGESTION_BUF 0x8E
10281029
#define LPFC_MBOX_OPCODE_GET_RSRC_EXTENT_INFO 0x9A
10291030
#define LPFC_MBOX_OPCODE_GET_ALLOC_RSRC_EXTENT 0x9B
10301031
#define LPFC_MBOX_OPCODE_ALLOC_RSRC_EXTENT 0x9C
@@ -3503,6 +3504,21 @@ struct lpfc_mbx_get_sli4_parameters {
35033504
struct lpfc_sli4_parameters sli4_parameters;
35043505
};
35053506

3507+
struct lpfc_mbx_reg_congestion_buf {
3508+
struct mbox_header header;
3509+
uint32_t word0;
3510+
#define lpfc_mbx_reg_cgn_buf_type_WORD word0
3511+
#define lpfc_mbx_reg_cgn_buf_type_SHIFT 0
3512+
#define lpfc_mbx_reg_cgn_buf_type_MASK 0xFF
3513+
#define lpfc_mbx_reg_cgn_buf_cnt_WORD word0
3514+
#define lpfc_mbx_reg_cgn_buf_cnt_SHIFT 16
3515+
#define lpfc_mbx_reg_cgn_buf_cnt_MASK 0xFF
3516+
uint32_t word1;
3517+
uint32_t length;
3518+
uint32_t addr_lo;
3519+
uint32_t addr_hi;
3520+
};
3521+
35063522
struct lpfc_rscr_desc_generic {
35073523
#define LPFC_RSRC_DESC_WSIZE 22
35083524
uint32_t desc[LPFC_RSRC_DESC_WSIZE];
@@ -3902,6 +3918,7 @@ struct lpfc_mqe {
39023918
struct lpfc_mbx_query_fw_config query_fw_cfg;
39033919
struct lpfc_mbx_set_beacon_config beacon_config;
39043920
struct lpfc_mbx_get_sli4_parameters get_sli4_parameters;
3921+
struct lpfc_mbx_reg_congestion_buf reg_congestion_buf;
39053922
struct lpfc_mbx_set_link_diag_state link_diag_state;
39063923
struct lpfc_mbx_set_link_diag_loopback link_diag_loopback;
39073924
struct lpfc_mbx_run_link_diag_test link_diag_test;

drivers/scsi/lpfc/lpfc_init.c

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12234,6 +12234,115 @@ lpfc_sli4_hba_unset(struct lpfc_hba *phba)
1223412234
phba->pport->work_port_events = 0;
1223512235
}
1223612236

12237+
12238+
void
12239+
lpfc_init_congestion_buf(struct lpfc_hba *phba)
12240+
{
12241+
lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT,
12242+
"6235 INIT Congestion Buffer %p\n", phba->cgn_i);
12243+
12244+
if (!phba->cgn_i)
12245+
return;
12246+
12247+
atomic_set(&phba->cgn_fabric_warn_cnt, 0);
12248+
atomic_set(&phba->cgn_fabric_alarm_cnt, 0);
12249+
atomic_set(&phba->cgn_sync_alarm_cnt, 0);
12250+
atomic_set(&phba->cgn_sync_warn_cnt, 0);
12251+
12252+
atomic64_set(&phba->cgn_acqe_stat.alarm, 0);
12253+
atomic64_set(&phba->cgn_acqe_stat.warn, 0);
12254+
atomic_set(&phba->cgn_driver_evt_cnt, 0);
12255+
atomic_set(&phba->cgn_latency_evt_cnt, 0);
12256+
atomic64_set(&phba->cgn_latency_evt, 0);
12257+
phba->cgn_evt_minute = 0;
12258+
12259+
phba->cgn_evt_timestamp = jiffies +
12260+
msecs_to_jiffies(LPFC_CGN_TIMER_TO_MIN);
12261+
}
12262+
12263+
void
12264+
lpfc_init_congestion_stat(struct lpfc_hba *phba)
12265+
{
12266+
lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT,
12267+
"6236 INIT Congestion Stat %p\n", phba->cgn_i);
12268+
12269+
if (!phba->cgn_i)
12270+
return;
12271+
}
12272+
12273+
/**
12274+
* __lpfc_reg_congestion_buf - register congestion info buffer with HBA
12275+
* @phba: Pointer to hba context object.
12276+
* @reg: flag to determine register or unregister.
12277+
*/
12278+
static int
12279+
__lpfc_reg_congestion_buf(struct lpfc_hba *phba, int reg)
12280+
{
12281+
struct lpfc_mbx_reg_congestion_buf *reg_congestion_buf;
12282+
union lpfc_sli4_cfg_shdr *shdr;
12283+
uint32_t shdr_status, shdr_add_status;
12284+
LPFC_MBOXQ_t *mboxq;
12285+
int length, rc;
12286+
12287+
if (!phba->cgn_i)
12288+
return -ENXIO;
12289+
12290+
mboxq = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL);
12291+
if (!mboxq) {
12292+
lpfc_printf_log(phba, KERN_ERR, LOG_MBOX,
12293+
"2641 REG_CONGESTION_BUF mbox allocation fail: "
12294+
"HBA state x%x reg %d\n",
12295+
phba->pport->port_state, reg);
12296+
return -ENOMEM;
12297+
}
12298+
12299+
length = (sizeof(struct lpfc_mbx_reg_congestion_buf) -
12300+
sizeof(struct lpfc_sli4_cfg_mhdr));
12301+
lpfc_sli4_config(phba, mboxq, LPFC_MBOX_SUBSYSTEM_COMMON,
12302+
LPFC_MBOX_OPCODE_REG_CONGESTION_BUF, length,
12303+
LPFC_SLI4_MBX_EMBED);
12304+
reg_congestion_buf = &mboxq->u.mqe.un.reg_congestion_buf;
12305+
bf_set(lpfc_mbx_reg_cgn_buf_type, reg_congestion_buf, 1);
12306+
if (reg > 0)
12307+
bf_set(lpfc_mbx_reg_cgn_buf_cnt, reg_congestion_buf, 1);
12308+
else
12309+
bf_set(lpfc_mbx_reg_cgn_buf_cnt, reg_congestion_buf, 0);
12310+
reg_congestion_buf->length = sizeof(struct lpfc_cgn_info);
12311+
reg_congestion_buf->addr_lo =
12312+
putPaddrLow(phba->cgn_i->phys);
12313+
reg_congestion_buf->addr_hi =
12314+
putPaddrHigh(phba->cgn_i->phys);
12315+
12316+
rc = lpfc_sli_issue_mbox(phba, mboxq, MBX_POLL);
12317+
shdr = (union lpfc_sli4_cfg_shdr *)
12318+
&mboxq->u.mqe.un.sli4_config.header.cfg_shdr;
12319+
shdr_status = bf_get(lpfc_mbox_hdr_status, &shdr->response);
12320+
shdr_add_status = bf_get(lpfc_mbox_hdr_add_status,
12321+
&shdr->response);
12322+
mempool_free(mboxq, phba->mbox_mem_pool);
12323+
if (shdr_status || shdr_add_status || rc) {
12324+
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
12325+
"2642 REG_CONGESTION_BUF mailbox "
12326+
"failed with status x%x add_status x%x,"
12327+
" mbx status x%x reg %d\n",
12328+
shdr_status, shdr_add_status, rc, reg);
12329+
return -ENXIO;
12330+
}
12331+
return 0;
12332+
}
12333+
12334+
static int
12335+
lpfc_unreg_congestion_buf(struct lpfc_hba *phba)
12336+
{
12337+
return __lpfc_reg_congestion_buf(phba, 0);
12338+
}
12339+
12340+
int
12341+
lpfc_reg_congestion_buf(struct lpfc_hba *phba)
12342+
{
12343+
return __lpfc_reg_congestion_buf(phba, 1);
12344+
}
12345+
1223712346
/**
1223812347
* lpfc_get_sli4_parameters - Get the SLI4 Config PARAMETERS.
1223912348
* @phba: Pointer to HBA context object.

drivers/scsi/lpfc/lpfc_sli.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7713,6 +7713,16 @@ lpfc_cmf_setup(struct lpfc_hba *phba)
77137713
sli4_params->mi_ver);
77147714

77157715
mempool_free(mboxq, phba->mbox_mem_pool);
7716+
7717+
/* Initialize atomic counters */
7718+
atomic_set(&phba->cgn_fabric_warn_cnt, 0);
7719+
atomic_set(&phba->cgn_fabric_alarm_cnt, 0);
7720+
atomic_set(&phba->cgn_sync_alarm_cnt, 0);
7721+
atomic_set(&phba->cgn_sync_warn_cnt, 0);
7722+
atomic_set(&phba->cgn_driver_evt_cnt, 0);
7723+
atomic_set(&phba->cgn_latency_evt_cnt, 0);
7724+
atomic64_set(&phba->cgn_latency_evt, 0);
7725+
77167726
return 0;
77177727
}
77187728

0 commit comments

Comments
 (0)