Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

scsi: lpfc: Add cmf_info sysfs entry

Allow abbreviated cm framework status information to be obtained via sysfs.

Link: https://lore.kernel.org/r/20210816162901.121235-14-jsmart2021@gmail.com
Co-developed-by: Justin Tee <justin.tee@broadcom.com>
Signed-off-by: Justin Tee <justin.tee@broadcom.com>
Signed-off-by: James Smart <jsmart2021@gmail.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

authored by

James Smart and committed by
Martin K. Petersen
74a7baa2 9f778708

+235 -10
+1
drivers/scsi/lpfc/lpfc.h
··· 1600 1600 }; 1601 1601 1602 1602 #define LPFC_MAX_RXMONITOR_ENTRY 800 1603 + #define LPFC_MAX_RXMONITOR_DUMP 32 1603 1604 struct rxtable_entry { 1604 1605 uint64_t total_bytes; /* Total no of read bytes requested */ 1605 1606 uint64_t rcv_bytes; /* Total no of read bytes completed */
+189 -4
drivers/scsi/lpfc/lpfc_attr.c
··· 57 57 #define LPFC_MIN_DEVLOSS_TMO 1 58 58 #define LPFC_MAX_DEVLOSS_TMO 255 59 59 60 + #define LPFC_MAX_INFO_TMP_LEN 100 61 + #define LPFC_INFO_MORE_STR "\nCould be more info...\n" 60 62 /* 61 63 * Write key size should be multiple of 4. If write key is changed 62 64 * make sure that library write key is also changed. ··· 112 110 } 113 111 hdw[8] = 0; 114 112 return; 113 + } 114 + 115 + static ssize_t 116 + lpfc_cmf_info_show(struct device *dev, struct device_attribute *attr, 117 + char *buf) 118 + { 119 + struct Scsi_Host *shost = class_to_shost(dev); 120 + struct lpfc_vport *vport = (struct lpfc_vport *)shost->hostdata; 121 + struct lpfc_hba *phba = vport->phba; 122 + struct lpfc_cgn_info *cp = NULL; 123 + struct lpfc_cgn_stat *cgs; 124 + int len = 0; 125 + int cpu; 126 + u64 rcv, total; 127 + char tmp[LPFC_MAX_INFO_TMP_LEN] = {0}; 128 + 129 + if (phba->cgn_i) 130 + cp = (struct lpfc_cgn_info *)phba->cgn_i->virt; 131 + 132 + scnprintf(tmp, sizeof(tmp), 133 + "Congestion Mgmt Info: E2Eattr %d Ver %d " 134 + "CMF %d cnt %d\n", 135 + phba->sli4_hba.pc_sli4_params.mi_ver, 136 + cp ? cp->cgn_info_version : 0, 137 + phba->sli4_hba.pc_sli4_params.cmf, phba->cmf_timer_cnt); 138 + 139 + if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE) 140 + goto buffer_done; 141 + 142 + if (!phba->sli4_hba.pc_sli4_params.cmf) 143 + goto buffer_done; 144 + 145 + switch (phba->cgn_init_reg_signal) { 146 + case EDC_CG_SIG_WARN_ONLY: 147 + scnprintf(tmp, sizeof(tmp), 148 + "Register: Init: Signal:WARN "); 149 + break; 150 + case EDC_CG_SIG_WARN_ALARM: 151 + scnprintf(tmp, sizeof(tmp), 152 + "Register: Init: Signal:WARN|ALARM "); 153 + break; 154 + default: 155 + scnprintf(tmp, sizeof(tmp), 156 + "Register: Init: Signal:NONE "); 157 + break; 158 + } 159 + if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE) 160 + goto buffer_done; 161 + 162 + switch (phba->cgn_init_reg_fpin) { 163 + case LPFC_CGN_FPIN_WARN: 164 + scnprintf(tmp, sizeof(tmp), 165 + "FPIN:WARN\n"); 166 + break; 167 + case LPFC_CGN_FPIN_ALARM: 168 + scnprintf(tmp, sizeof(tmp), 169 + "FPIN:ALARM\n"); 170 + break; 171 + case LPFC_CGN_FPIN_BOTH: 172 + scnprintf(tmp, sizeof(tmp), 173 + "FPIN:WARN|ALARM\n"); 174 + break; 175 + default: 176 + scnprintf(tmp, sizeof(tmp), 177 + "FPIN:NONE\n"); 178 + break; 179 + } 180 + if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE) 181 + goto buffer_done; 182 + 183 + switch (phba->cgn_reg_signal) { 184 + case EDC_CG_SIG_WARN_ONLY: 185 + scnprintf(tmp, sizeof(tmp), 186 + " Current: Signal:WARN "); 187 + break; 188 + case EDC_CG_SIG_WARN_ALARM: 189 + scnprintf(tmp, sizeof(tmp), 190 + " Current: Signal:WARN|ALARM "); 191 + break; 192 + default: 193 + scnprintf(tmp, sizeof(tmp), 194 + " Current: Signal:NONE "); 195 + break; 196 + } 197 + if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE) 198 + goto buffer_done; 199 + 200 + switch (phba->cgn_reg_fpin) { 201 + case LPFC_CGN_FPIN_WARN: 202 + scnprintf(tmp, sizeof(tmp), 203 + "FPIN:WARN ACQEcnt:%d\n", phba->cgn_acqe_cnt); 204 + break; 205 + case LPFC_CGN_FPIN_ALARM: 206 + scnprintf(tmp, sizeof(tmp), 207 + "FPIN:ALARM ACQEcnt:%d\n", phba->cgn_acqe_cnt); 208 + break; 209 + case LPFC_CGN_FPIN_BOTH: 210 + scnprintf(tmp, sizeof(tmp), 211 + "FPIN:WARN|ALARM ACQEcnt:%d\n", phba->cgn_acqe_cnt); 212 + break; 213 + default: 214 + scnprintf(tmp, sizeof(tmp), 215 + "FPIN:NONE ACQEcnt:%d\n", phba->cgn_acqe_cnt); 216 + break; 217 + } 218 + if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE) 219 + goto buffer_done; 220 + 221 + if (phba->cmf_active_mode != phba->cgn_p.cgn_param_mode) { 222 + switch (phba->cmf_active_mode) { 223 + case LPFC_CFG_OFF: 224 + scnprintf(tmp, sizeof(tmp), "Active: Mode:Off\n"); 225 + break; 226 + case LPFC_CFG_MANAGED: 227 + scnprintf(tmp, sizeof(tmp), "Active: Mode:Managed\n"); 228 + break; 229 + case LPFC_CFG_MONITOR: 230 + scnprintf(tmp, sizeof(tmp), "Active: Mode:Monitor\n"); 231 + break; 232 + default: 233 + scnprintf(tmp, sizeof(tmp), "Active: Mode:Unknown\n"); 234 + } 235 + if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE) 236 + goto buffer_done; 237 + } 238 + 239 + switch (phba->cgn_p.cgn_param_mode) { 240 + case LPFC_CFG_OFF: 241 + scnprintf(tmp, sizeof(tmp), "Config: Mode:Off "); 242 + break; 243 + case LPFC_CFG_MANAGED: 244 + scnprintf(tmp, sizeof(tmp), "Config: Mode:Managed "); 245 + break; 246 + case LPFC_CFG_MONITOR: 247 + scnprintf(tmp, sizeof(tmp), "Config: Mode:Monitor "); 248 + break; 249 + default: 250 + scnprintf(tmp, sizeof(tmp), "Config: Mode:Unknown "); 251 + } 252 + if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE) 253 + goto buffer_done; 254 + 255 + total = 0; 256 + rcv = 0; 257 + for_each_present_cpu(cpu) { 258 + cgs = per_cpu_ptr(phba->cmf_stat, cpu); 259 + total += atomic64_read(&cgs->total_bytes); 260 + rcv += atomic64_read(&cgs->rcv_bytes); 261 + } 262 + 263 + scnprintf(tmp, sizeof(tmp), 264 + "IObusy:%d Info:%d Bytes: Rcv:x%llx Total:x%llx\n", 265 + atomic_read(&phba->cmf_busy), 266 + phba->cmf_active_info, rcv, total); 267 + if (strlcat(buf, tmp, PAGE_SIZE) >= PAGE_SIZE) 268 + goto buffer_done; 269 + 270 + scnprintf(tmp, sizeof(tmp), 271 + "Port_speed:%d Link_byte_cnt:%ld " 272 + "Max_byte_per_interval:%ld\n", 273 + lpfc_sli_port_speed_get(phba), 274 + (unsigned long)phba->cmf_link_byte_count, 275 + (unsigned long)phba->cmf_max_bytes_per_interval); 276 + strlcat(buf, tmp, PAGE_SIZE); 277 + 278 + buffer_done: 279 + len = strnlen(buf, PAGE_SIZE); 280 + 281 + if (unlikely(len >= (PAGE_SIZE - 1))) { 282 + lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT, 283 + "6312 Catching potential buffer " 284 + "overflow > PAGE_SIZE = %lu bytes\n", 285 + PAGE_SIZE); 286 + strscpy(buf + PAGE_SIZE - 1 - 287 + strnlen(LPFC_INFO_MORE_STR, PAGE_SIZE - 1), 288 + LPFC_INFO_MORE_STR, 289 + strnlen(LPFC_INFO_MORE_STR, PAGE_SIZE - 1) 290 + + 1); 291 + } 292 + return len; 115 293 } 116 294 117 295 /** ··· 350 168 char *statep; 351 169 int i; 352 170 int len = 0; 353 - char tmp[LPFC_MAX_NVME_INFO_TMP_LEN] = {0}; 171 + char tmp[LPFC_MAX_INFO_TMP_LEN] = {0}; 354 172 355 173 if (!(vport->cfg_enable_fc4_type & LPFC_ENABLE_NVME)) { 356 174 len = scnprintf(buf, PAGE_SIZE, "NVME Disabled\n"); ··· 694 512 "6314 Catching potential buffer " 695 513 "overflow > PAGE_SIZE = %lu bytes\n", 696 514 PAGE_SIZE); 697 - strlcpy(buf + PAGE_SIZE - 1 - sizeof(LPFC_NVME_INFO_MORE_STR), 698 - LPFC_NVME_INFO_MORE_STR, 699 - sizeof(LPFC_NVME_INFO_MORE_STR) + 1); 515 + strscpy(buf + PAGE_SIZE - 1 - sizeof(LPFC_INFO_MORE_STR), 516 + LPFC_INFO_MORE_STR, 517 + sizeof(LPFC_INFO_MORE_STR) + 1); 700 518 } 701 519 702 520 return len; ··· 2818 2636 static DEVICE_ATTR(protocol, S_IRUGO, lpfc_sli4_protocol_show, NULL); 2819 2637 static DEVICE_ATTR(lpfc_xlane_supported, S_IRUGO, lpfc_oas_supported_show, 2820 2638 NULL); 2639 + static DEVICE_ATTR(cmf_info, 0444, lpfc_cmf_info_show, NULL); 2821 2640 2822 2641 static char *lpfc_soft_wwn_key = "C99G71SL8032A"; 2823 2642 #define WWN_SZ 8 ··· 6515 6332 &dev_attr_lpfc_enable_bbcr, 6516 6333 &dev_attr_lpfc_enable_dpp, 6517 6334 &dev_attr_lpfc_enable_mi, 6335 + &dev_attr_cmf_info, 6518 6336 &dev_attr_lpfc_max_vmid, 6519 6337 &dev_attr_lpfc_vmid_inactivity_timeout, 6520 6338 &dev_attr_lpfc_vmid_app_header, ··· 6546 6362 &dev_attr_lpfc_max_scsicmpl_time, 6547 6363 &dev_attr_lpfc_stat_data_ctrl, 6548 6364 &dev_attr_lpfc_static_vport, 6365 + &dev_attr_cmf_info, 6549 6366 NULL, 6550 6367 }; 6551 6368
+2
drivers/scsi/lpfc/lpfc_crtn.h
··· 86 86 uint32_t lpfc_cgn_calc_crc32(void *bufp, uint32_t sz, uint32_t seed); 87 87 int lpfc_config_cgn_signal(struct lpfc_hba *phba); 88 88 int lpfc_issue_cmf_sync_wqe(struct lpfc_hba *phba, u32 ms, u64 total); 89 + void lpfc_cgn_dump_rxmonitor(struct lpfc_hba *phba); 89 90 void lpfc_cgn_update_stat(struct lpfc_hba *phba, uint32_t dtag); 90 91 void lpfc_unblock_requests(struct lpfc_hba *phba); 91 92 void lpfc_block_requests(struct lpfc_hba *phba); ··· 160 159 int lpfc_issue_fabric_reglogin(struct lpfc_vport *); 161 160 int lpfc_issue_els_rdf(struct lpfc_vport *vport, uint8_t retry); 162 161 int lpfc_issue_els_edc(struct lpfc_vport *vport, uint8_t retry); 162 + void lpfc_els_rcv_fpin(struct lpfc_vport *vport, void *p, u32 fpin_length); 163 163 int lpfc_els_free_iocb(struct lpfc_hba *, struct lpfc_iocbq *); 164 164 int lpfc_ct_free_iocb(struct lpfc_hba *, struct lpfc_iocbq *); 165 165 int lpfc_els_rsp_acc(struct lpfc_vport *, uint32_t, struct lpfc_iocbq *,
+1 -1
drivers/scsi/lpfc/lpfc_els.c
··· 9632 9632 return rc; 9633 9633 } 9634 9634 9635 - static void 9635 + void 9636 9636 lpfc_els_rcv_fpin(struct lpfc_vport *vport, void *p, u32 fpin_length) 9637 9637 { 9638 9638 struct lpfc_hba *phba = vport->phba;
+4 -2
drivers/scsi/lpfc/lpfc_hw4.h
··· 1157 1157 void *addr[LPFC_SLI4_MBX_SGE_MAX_PAGES]; 1158 1158 }; 1159 1159 1160 + #define LPFC_MBX_OBJECT_NAME_LEN_DW 26 1160 1161 struct lpfc_mbx_read_object { /* Version 0 */ 1161 1162 struct mbox_header header; 1162 1163 union { ··· 1167 1166 #define lpfc_mbx_rd_object_rlen_MASK 0x00FFFFFF 1168 1167 #define lpfc_mbx_rd_object_rlen_WORD word0 1169 1168 uint32_t rd_object_offset; 1170 - uint32_t rd_object_name[26]; 1169 + uint32_t rd_object_name[LPFC_MBX_OBJECT_NAME_LEN_DW]; 1171 1170 #define LPFC_OBJ_NAME_SZ 104 /* 26 x sizeof(uint32_t) is 104. */ 1172 1171 uint32_t rd_object_cnt; 1173 1172 struct lpfc_mbx_host_buf rd_object_hbuf[4]; ··· 3872 3871 #define MB_CEQ_STATUS_QUEUE_FLUSHING 0x4 3873 3872 #define MB_CQE_STATUS_DMA_FAILED 0x5 3874 3873 3874 + 3875 3875 #define LPFC_MBX_WR_CONFIG_MAX_BDE 1 3876 3876 struct lpfc_mbx_wr_object { 3877 3877 struct mbox_header header; ··· 3889 3887 #define lpfc_wr_object_write_length_MASK 0x00FFFFFF 3890 3888 #define lpfc_wr_object_write_length_WORD word4 3891 3889 uint32_t write_offset; 3892 - uint32_t object_name[26]; 3890 + uint32_t object_name[LPFC_MBX_OBJECT_NAME_LEN_DW]; 3893 3891 uint32_t bde_count; 3894 3892 struct ulp_bde64 bde[LPFC_MBX_WR_CONFIG_MAX_BDE]; 3895 3893 } request;
+38
drivers/scsi/lpfc/lpfc_init.c
··· 5404 5404 return port_speed; 5405 5405 } 5406 5406 5407 + void 5408 + lpfc_cgn_dump_rxmonitor(struct lpfc_hba *phba) 5409 + { 5410 + struct rxtable_entry *entry; 5411 + int cnt = 0, head, tail, last, start; 5412 + 5413 + head = atomic_read(&phba->rxtable_idx_head); 5414 + tail = atomic_read(&phba->rxtable_idx_tail); 5415 + if (!phba->rxtable || head == tail) { 5416 + lpfc_printf_log(phba, KERN_ERR, LOG_CGN_MGMT, 5417 + "4411 Rxtable is empty\n"); 5418 + return; 5419 + } 5420 + last = tail; 5421 + start = head; 5422 + 5423 + /* Display the last LPFC_MAX_RXMONITOR_DUMP entries from the rxtable */ 5424 + while (start != last) { 5425 + if (start) 5426 + start--; 5427 + else 5428 + start = LPFC_MAX_RXMONITOR_ENTRY - 1; 5429 + entry = &phba->rxtable[start]; 5430 + lpfc_printf_log(phba, KERN_INFO, LOG_CGN_MGMT, 5431 + "4410 %02d: MBPI %lld Xmit %lld Cmpl %lld " 5432 + "Lat %lld ASz %lld Info %02d BWUtil %d " 5433 + "Int %d slot %d\n", 5434 + cnt, entry->max_bytes_per_interval, 5435 + entry->total_bytes, entry->rcv_bytes, 5436 + entry->avg_io_latency, entry->avg_io_size, 5437 + entry->cmf_info, entry->timer_utilization, 5438 + entry->timer_interval, start); 5439 + cnt++; 5440 + if (cnt >= LPFC_MAX_RXMONITOR_DUMP) 5441 + return; 5442 + } 5443 + } 5444 + 5407 5445 /** 5408 5446 * lpfc_cgn_update_stat - Save data into congestion stats buffer 5409 5447 * @phba: pointer to lpfc hba data structure.
-3
drivers/scsi/lpfc/lpfc_nvme.h
··· 34 34 #define LPFC_NVME_FB_SHIFT 9 35 35 #define LPFC_NVME_MAX_FB (1 << 20) /* 1M */ 36 36 37 - #define LPFC_MAX_NVME_INFO_TMP_LEN 100 38 - #define LPFC_NVME_INFO_MORE_STR "\nCould be more info...\n" 39 - 40 37 #define lpfc_ndlp_get_nrport(ndlp) \ 41 38 ((!ndlp->nrport || (ndlp->fc4_xpt_flags & NVME_XPT_UNREG_WAIT))\ 42 39 ? NULL : ndlp->nrport)