Skip to content

Commit 0224383

Browse files
jsmart-ghmartinkpetersen
authored andcommitted
scsi: lpfc: Add support for the CM framework
Complete the enablement of the cm framework feature in the adapter. Perform the following: - Detect the presence of the congestion management framework feature. When the cm framework is present: - Issue the SET_FEATURE command to enable the feature. - Register the cm statistics buffer with the adapter. - Read the cm enablement buffer to determine the cm framework state for cm management. When cm management is enabled: - Monitor all FPIN and congestion signalling events, incrementing counters. - Regularly sync with the adapter to communicate congestion events and to receive an rx request limit. - Monitor requests for rx data and ensure that no more than the adapter prescribed limit is issued on the link. If the limit is exceeded, SCSI and/or NVMe traffic is temporarily suspended. - Maintain the minute, hourly, daily statistics buffer. - Monitor for congestion enablement change events, causing a reread of the enablement buffer and acting on any change in enablement. And: - Add teardown logic, including buffer deregistration, on adapter detachment or reset. 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 daebf93 commit 0224383

File tree

12 files changed

+912
-34
lines changed

12 files changed

+912
-34
lines changed

drivers/scsi/lpfc/lpfc.h

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,14 @@ struct lpfc_cgn_info {
550550
#define LPFC_CGN_INFO_SZ (sizeof(struct lpfc_cgn_info) - \
551551
sizeof(uint32_t))
552552

553+
struct lpfc_cgn_stat {
554+
atomic64_t total_bytes;
555+
atomic64_t rcv_bytes;
556+
atomic64_t rx_latency;
557+
#define LPFC_CGN_NOT_SENT 0xFFFFFFFFFFFFFFFFLL
558+
atomic_t rx_io_cnt;
559+
};
560+
553561
struct lpfc_cgn_acqe_stat {
554562
atomic64_t alarm;
555563
atomic64_t warn;
@@ -1021,7 +1029,10 @@ struct lpfc_hba {
10211029
* capability
10221030
*/
10231031
#define HBA_FLOGI_ISSUED 0x100000 /* FLOGI was issued */
1032+
#define HBA_CGN_RSVD1 0x200000 /* Reserved CGN flag */
1033+
#define HBA_CGN_DAY_WRAP 0x400000 /* HBA Congestion info day wraps */
10241034
#define HBA_DEFER_FLOGI 0x800000 /* Defer FLOGI till read_sparm cmpl */
1035+
#define HBA_SETUP 0x1000000 /* Signifies HBA setup is completed */
10251036
#define HBA_NEEDS_CFG_PORT 0x2000000 /* SLI3 - needs a CONFIG_PORT mbox */
10261037
#define HBA_HBEAT_INP 0x4000000 /* mbox HBEAT is in progress */
10271038
#define HBA_HBEAT_TMO 0x8000000 /* HBEAT initiated after timeout */
@@ -1272,6 +1283,7 @@ struct lpfc_hba {
12721283
uint32_t total_iocbq_bufs;
12731284
struct list_head active_rrq_list;
12741285
spinlock_t hbalock;
1286+
struct work_struct unblock_request_work; /* SCSI layer unblock IOs */
12751287

12761288
/* dma_mem_pools */
12771289
struct dma_pool *lpfc_sg_dma_buf_pool;
@@ -1496,12 +1508,25 @@ struct lpfc_hba {
14961508
uint64_t ktime_seg10_max;
14971509
#endif
14981510
/* CMF objects */
1499-
u32 cmf_active_mode;
1500-
#define LPFC_CFG_OFF 0
1501-
1511+
struct lpfc_cgn_stat __percpu *cmf_stat;
1512+
uint32_t cmf_interval_rate; /* timer interval limit in ms */
1513+
uint32_t cmf_timer_cnt;
15021514
#define LPFC_CMF_INTERVAL 90
1515+
uint64_t cmf_link_byte_count;
1516+
uint64_t cmf_max_line_rate;
1517+
uint64_t cmf_max_bytes_per_interval;
1518+
uint64_t cmf_last_sync_bw;
15031519
#define LPFC_CMF_BLK_SIZE 512
1520+
struct hrtimer cmf_timer;
1521+
atomic_t cmf_bw_wait;
1522+
atomic_t cmf_busy;
1523+
atomic_t cmf_stop_io; /* To block request and stop IO's */
1524+
uint32_t cmf_active_mode;
1525+
uint32_t cmf_info_per_interval;
15041526
#define LPFC_MAX_CMF_INFO 32
1527+
struct timespec64 cmf_latency; /* Interval congestion timestamp */
1528+
uint32_t cmf_last_ts; /* Interval congestion time (ms) */
1529+
uint32_t cmf_active_info;
15051530

15061531
/* Signal / FPIN handling for Congestion Mgmt */
15071532
u8 cgn_reg_fpin; /* Negotiated value from RDF */
@@ -1521,6 +1546,8 @@ struct lpfc_hba {
15211546
u32 cgn_sig_freq;
15221547
u32 cgn_acqe_cnt;
15231548

1549+
uint64_t rx_block_cnt;
1550+
15241551
/* Congestion parameters from flash */
15251552
struct lpfc_cgn_param cgn_p;
15261553

drivers/scsi/lpfc/lpfc_attr.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7476,6 +7476,7 @@ lpfc_get_cfgparam(struct lpfc_hba *phba)
74767476
lpfc_enable_dpp_init(phba, lpfc_enable_dpp);
74777477
lpfc_enable_mi_init(phba, lpfc_enable_mi);
74787478

7479+
phba->cgn_p.cgn_param_mode = LPFC_CFG_OFF;
74797480
phba->cmf_active_mode = LPFC_CFG_OFF;
74807481
if (lpfc_fabric_cgn_frequency > EDC_CG_SIGFREQ_CNT_MAX ||
74817482
lpfc_fabric_cgn_frequency < EDC_CG_SIGFREQ_CNT_MIN)

drivers/scsi/lpfc/lpfc_crtn.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ 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 *);
6161
int lpfc_reg_congestion_buf(struct lpfc_hba *phba);
62+
int lpfc_unreg_congestion_buf(struct lpfc_hba *phba);
6263
struct lpfc_vport *lpfc_find_vport_by_did(struct lpfc_hba *, uint32_t);
6364
void lpfc_cleanup_rcv_buffers(struct lpfc_vport *);
6465
void lpfc_rcv_seq_check_edtov(struct lpfc_vport *);
@@ -75,11 +76,17 @@ int lpfc_init_iocb_list(struct lpfc_hba *phba, int cnt);
7576
void lpfc_free_iocb_list(struct lpfc_hba *phba);
7677
int lpfc_post_rq_buffer(struct lpfc_hba *phba, struct lpfc_queue *hrq,
7778
struct lpfc_queue *drq, int count, int idx);
79+
uint32_t lpfc_calc_cmf_latency(struct lpfc_hba *phba);
80+
void lpfc_cmf_signal_init(struct lpfc_hba *phba);
81+
void lpfc_cmf_start(struct lpfc_hba *phba);
82+
void lpfc_cmf_stop(struct lpfc_hba *phba);
7883
void lpfc_init_congestion_stat(struct lpfc_hba *phba);
7984
void lpfc_init_congestion_buf(struct lpfc_hba *phba);
8085
int lpfc_sli4_cgn_params_read(struct lpfc_hba *phba);
8186
int lpfc_config_cgn_signal(struct lpfc_hba *phba);
8287
int lpfc_issue_cmf_sync_wqe(struct lpfc_hba *phba, u32 ms, u64 total);
88+
void lpfc_unblock_requests(struct lpfc_hba *phba);
89+
void lpfc_block_requests(struct lpfc_hba *phba);
8390

8491
void lpfc_mbx_cmpl_local_config_link(struct lpfc_hba *, LPFC_MBOXQ_t *);
8592
void lpfc_mbx_cmpl_reg_login(struct lpfc_hba *, LPFC_MBOXQ_t *);
@@ -471,6 +478,9 @@ void lpfc_free_fast_evt(struct lpfc_hba *, struct lpfc_fast_path_event *);
471478
void lpfc_create_static_vport(struct lpfc_hba *);
472479
void lpfc_stop_hba_timers(struct lpfc_hba *);
473480
void lpfc_stop_port(struct lpfc_hba *);
481+
int lpfc_update_cmf_cmd(struct lpfc_hba *phba, uint32_t sz);
482+
int lpfc_update_cmf_cmpl(struct lpfc_hba *phba, uint64_t val, uint32_t sz,
483+
struct Scsi_Host *shost);
474484
void __lpfc_sli4_stop_fcf_redisc_wait_timer(struct lpfc_hba *);
475485
void lpfc_sli4_stop_fcf_redisc_wait_timer(struct lpfc_hba *);
476486
void lpfc_parse_fcoe_conf(struct lpfc_hba *, uint8_t *, uint32_t);

drivers/scsi/lpfc/lpfc_els.c

Lines changed: 69 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3333,9 +3333,11 @@ lpfc_cmpl_els_disc_cmd(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
33333333
lpfc_printf_vlog(vport, KERN_INFO,
33343334
LOG_ELS | LOG_CGN_MGMT,
33353335
"4677 Fabric RDF Notification Grant "
3336-
"Data: 0x%08x\n",
3336+
"Data: 0x%08x Reg: %x %x\n",
33373337
be32_to_cpu(
3338-
prdf->reg_d1.desc_tags[i]));
3338+
prdf->reg_d1.desc_tags[i]),
3339+
phba->cgn_reg_signal,
3340+
phba->cgn_reg_fpin);
33393341
}
33403342

33413343
out:
@@ -3702,9 +3704,11 @@ lpfc_issue_els_rdf(struct lpfc_vport *vport, uint8_t retry)
37023704
prdf->reg_d1.desc_tags[3] = cpu_to_be32(ELS_DTAG_CONGESTION);
37033705

37043706
lpfc_printf_vlog(vport, KERN_INFO, LOG_ELS | LOG_CGN_MGMT,
3705-
"6444 Xmit RDF to remote NPORT x%x\n",
3706-
ndlp->nlp_DID);
3707+
"6444 Xmit RDF to remote NPORT x%x Reg: %x %x\n",
3708+
ndlp->nlp_DID, phba->cgn_reg_signal,
3709+
phba->cgn_reg_fpin);
37073710

3711+
phba->cgn_fpin_frequency = LPFC_FPIN_INIT_FREQ;
37083712
elsiocb->iocb_cmpl = lpfc_cmpl_els_disc_cmd;
37093713
elsiocb->context1 = lpfc_nlp_get(ndlp);
37103714
if (!elsiocb->context1) {
@@ -3778,6 +3782,8 @@ lpfc_least_capable_settings(struct lpfc_hba *phba,
37783782
{
37793783
u32 rsp_sig_cap = 0, drv_sig_cap = 0;
37803784
u32 rsp_sig_freq_cyc = 0, rsp_sig_freq_scale = 0;
3785+
struct lpfc_cgn_info *cp;
3786+
u16 sig_freq;
37813787

37823788
/* Get rsp signal and frequency capabilities. */
37833789
rsp_sig_cap = be32_to_cpu(pcgd->xmt_signal_capability);
@@ -3832,6 +3838,24 @@ lpfc_least_capable_settings(struct lpfc_hba *phba,
38323838
phba->cgn_reg_fpin &= ~LPFC_CGN_FPIN_WARN;
38333839
}
38343840
}
3841+
3842+
if (!phba->cgn_i)
3843+
return;
3844+
3845+
/* Update signal frequency in congestion info buffer */
3846+
cp = (struct lpfc_cgn_info *)phba->cgn_i->virt;
3847+
3848+
/* Frequency (in ms) Signal Warning/Signal Congestion Notifications
3849+
* are received by the HBA
3850+
*/
3851+
sig_freq = phba->cgn_sig_freq;
3852+
3853+
if (phba->cgn_reg_signal == EDC_CG_SIG_WARN_ONLY)
3854+
cp->cgn_warn_freq = cpu_to_le16(sig_freq);
3855+
if (phba->cgn_reg_signal == EDC_CG_SIG_WARN_ALARM) {
3856+
cp->cgn_alarm_freq = cpu_to_le16(sig_freq);
3857+
cp->cgn_warn_freq = cpu_to_le16(sig_freq);
3858+
}
38353859
return;
38363860

38373861
out_no_support:
@@ -9508,11 +9532,13 @@ lpfc_els_rcv_fpin_peer_cgn(struct lpfc_hba *phba, struct fc_tlv_desc *tlv)
95089532
static int
95099533
lpfc_els_rcv_fpin_cgn(struct lpfc_hba *phba, struct fc_tlv_desc *tlv)
95109534
{
9535+
struct lpfc_cgn_info *cp;
95119536
struct fc_fn_congn_desc *cgn = (struct fc_fn_congn_desc *)tlv;
95129537
const char *cgn_evt_str;
95139538
u32 cgn_evt;
95149539
const char *cgn_sev_str;
95159540
u32 cgn_sev;
9541+
uint16_t value;
95169542
bool nm_log = false;
95179543
int rc = 1;
95189544

@@ -9540,9 +9566,48 @@ lpfc_els_rcv_fpin_cgn(struct lpfc_hba *phba, struct fc_tlv_desc *tlv)
95409566
switch (cgn_sev) {
95419567
case FPIN_CONGN_SEVERITY_ERROR:
95429568
/* Take action here for an Alarm event */
9569+
if (phba->cmf_active_mode != LPFC_CFG_OFF) {
9570+
if (phba->cgn_reg_fpin & LPFC_CGN_FPIN_ALARM) {
9571+
/* Track of alarm cnt for cgn_info */
9572+
atomic_inc(&phba->cgn_fabric_alarm_cnt);
9573+
/* Track of alarm cnt for SYNC_WQE */
9574+
atomic_inc(&phba->cgn_sync_alarm_cnt);
9575+
}
9576+
goto cleanup;
9577+
}
95439578
break;
95449579
case FPIN_CONGN_SEVERITY_WARNING:
95459580
/* Take action here for a Warning event */
9581+
if (phba->cmf_active_mode != LPFC_CFG_OFF) {
9582+
if (phba->cgn_reg_fpin & LPFC_CGN_FPIN_WARN) {
9583+
/* Track of warning cnt for cgn_info */
9584+
atomic_inc(&phba->cgn_fabric_warn_cnt);
9585+
/* Track of warning cnt for SYNC_WQE */
9586+
atomic_inc(&phba->cgn_sync_warn_cnt);
9587+
}
9588+
cleanup:
9589+
/* Save frequency in ms */
9590+
phba->cgn_fpin_frequency =
9591+
be32_to_cpu(cgn->event_period);
9592+
value = phba->cgn_fpin_frequency;
9593+
if (phba->cgn_i) {
9594+
cp = (struct lpfc_cgn_info *)
9595+
phba->cgn_i->virt;
9596+
if (phba->cgn_reg_fpin &
9597+
LPFC_CGN_FPIN_ALARM)
9598+
cp->cgn_alarm_freq =
9599+
cpu_to_le16(value);
9600+
if (phba->cgn_reg_fpin &
9601+
LPFC_CGN_FPIN_WARN)
9602+
cp->cgn_warn_freq =
9603+
cpu_to_le16(value);
9604+
}
9605+
9606+
/* Don't deliver to upper layer since
9607+
* driver took action on this tlv.
9608+
*/
9609+
rc = 0;
9610+
}
95469611
break;
95479612
}
95489613
break;

drivers/scsi/lpfc/lpfc_hbadisc.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3647,6 +3647,10 @@ lpfc_mbx_cmpl_read_topology(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
36473647
phba->wait_4_mlo_maint_flg);
36483648
}
36493649
lpfc_mbx_process_link_up(phba, la);
3650+
3651+
if (phba->cmf_active_mode != LPFC_CFG_OFF)
3652+
lpfc_cmf_signal_init(phba);
3653+
36503654
} else if (attn_type == LPFC_ATT_LINK_DOWN ||
36513655
attn_type == LPFC_ATT_UNEXP_WWPN) {
36523656
phba->fc_stat.LinkDown++;

0 commit comments

Comments
 (0)