Skip to content

Commit 17b27ac

Browse files
jsmart-ghmartinkpetersen
authored andcommitted
scsi: lpfc: Add rx monitoring statistics
The driver provides overwatch of the cm behavior by maintaining a set of rx I/O statistics. This information is also used in later updating of the cm statistics buffer. 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 0224383 commit 17b27ac

File tree

5 files changed

+92
-0
lines changed

5 files changed

+92
-0
lines changed

drivers/scsi/lpfc/lpfc.h

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1546,6 +1546,12 @@ struct lpfc_hba {
15461546
u32 cgn_sig_freq;
15471547
u32 cgn_acqe_cnt;
15481548

1549+
/* RX monitor handling for CMF */
1550+
struct rxtable_entry *rxtable; /* RX_monitor information */
1551+
atomic_t rxtable_idx_head;
1552+
#define LPFC_RXMONITOR_TABLE_IN_USE (LPFC_MAX_RXMONITOR_ENTRY + 73)
1553+
atomic_t rxtable_idx_tail;
1554+
atomic_t rx_max_read_cnt; /* Maximum read bytes */
15491555
uint64_t rx_block_cnt;
15501556

15511557
/* Congestion parameters from flash */
@@ -1591,6 +1597,21 @@ struct lpfc_hba {
15911597
struct dbg_log_ent dbg_log[DBG_LOG_SZ];
15921598
};
15931599

1600+
#define LPFC_MAX_RXMONITOR_ENTRY 800
1601+
struct rxtable_entry {
1602+
uint64_t total_bytes; /* Total no of read bytes requested */
1603+
uint64_t rcv_bytes; /* Total no of read bytes completed */
1604+
uint64_t avg_io_size;
1605+
uint64_t avg_io_latency;/* Average io latency in microseconds */
1606+
uint64_t max_read_cnt; /* Maximum read bytes */
1607+
uint64_t max_bytes_per_interval;
1608+
uint32_t cmf_busy;
1609+
uint32_t cmf_info; /* CMF_SYNC_WQE info */
1610+
uint32_t io_cnt;
1611+
uint32_t timer_utilization;
1612+
uint32_t timer_interval;
1613+
};
1614+
15941615
static inline struct Scsi_Host *
15951616
lpfc_shost_from_vport(struct lpfc_vport *vport)
15961617
{

drivers/scsi/lpfc/lpfc_init.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5452,9 +5452,13 @@ lpfc_cmf_timer(struct hrtimer *timer)
54525452
{
54535453
struct lpfc_hba *phba = container_of(timer, struct lpfc_hba,
54545454
cmf_timer);
5455+
struct rxtable_entry *entry;
54555456
uint32_t io_cnt;
5457+
uint32_t head, tail;
5458+
uint32_t busy, max_read;
54565459
uint64_t total, rcv, lat, mbpi;
54575460
int timer_interval = LPFC_CMF_INTERVAL;
5461+
uint32_t ms;
54585462
struct lpfc_cgn_stat *cgs;
54595463
int cpu;
54605464

@@ -5479,6 +5483,14 @@ lpfc_cmf_timer(struct hrtimer *timer)
54795483
*/
54805484
atomic_set(&phba->cmf_stop_io, 1);
54815485

5486+
/* First we need to calculate the actual ms between
5487+
* the last timer interrupt and this one. We ask for
5488+
* LPFC_CMF_INTERVAL, however the actual time may
5489+
* vary depending on system overhead.
5490+
*/
5491+
ms = lpfc_calc_cmf_latency(phba);
5492+
5493+
54825494
/* Immediately after we calculate the time since the last
54835495
* timer interrupt, set the start time for the next
54845496
* interrupt
@@ -5525,6 +5537,8 @@ lpfc_cmf_timer(struct hrtimer *timer)
55255537
atomic_add(io_cnt, &phba->cgn_latency_evt_cnt);
55265538
atomic64_add(lat, &phba->cgn_latency_evt);
55275539
}
5540+
busy = atomic_xchg(&phba->cmf_busy, 0);
5541+
max_read = atomic_xchg(&phba->rx_max_read_cnt, 0);
55285542

55295543
/* Calculate MBPI for the next timer interval */
55305544
if (mbpi) {
@@ -5539,6 +5553,42 @@ lpfc_cmf_timer(struct hrtimer *timer)
55395553
phba->cmf_max_bytes_per_interval = mbpi;
55405554
}
55415555

5556+
/* Save rxmonitor information for debug */
5557+
if (phba->rxtable) {
5558+
head = atomic_xchg(&phba->rxtable_idx_head,
5559+
LPFC_RXMONITOR_TABLE_IN_USE);
5560+
entry = &phba->rxtable[head];
5561+
entry->total_bytes = total;
5562+
entry->rcv_bytes = rcv;
5563+
entry->cmf_busy = busy;
5564+
entry->cmf_info = phba->cmf_active_info;
5565+
if (io_cnt) {
5566+
entry->avg_io_latency = div_u64(lat, io_cnt);
5567+
entry->avg_io_size = div_u64(rcv, io_cnt);
5568+
} else {
5569+
entry->avg_io_latency = 0;
5570+
entry->avg_io_size = 0;
5571+
}
5572+
entry->max_read_cnt = max_read;
5573+
entry->io_cnt = io_cnt;
5574+
entry->max_bytes_per_interval = mbpi;
5575+
if (phba->cmf_active_mode == LPFC_CFG_MANAGED)
5576+
entry->timer_utilization = phba->cmf_last_ts;
5577+
else
5578+
entry->timer_utilization = ms;
5579+
entry->timer_interval = ms;
5580+
phba->cmf_last_ts = 0;
5581+
5582+
/* Increment rxtable index */
5583+
head = (head + 1) % LPFC_MAX_RXMONITOR_ENTRY;
5584+
tail = atomic_read(&phba->rxtable_idx_tail);
5585+
if (head == tail) {
5586+
tail = (tail + 1) % LPFC_MAX_RXMONITOR_ENTRY;
5587+
atomic_set(&phba->rxtable_idx_tail, tail);
5588+
}
5589+
atomic_set(&phba->rxtable_idx_head, head);
5590+
}
5591+
55425592
if (phba->cmf_active_mode == LPFC_CFG_MONITOR) {
55435593
/* If Monitor mode, check if we are oversubscribed
55445594
* against the full line rate.

drivers/scsi/lpfc/lpfc_mem.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -344,6 +344,10 @@ lpfc_mem_free_all(struct lpfc_hba *phba)
344344
phba->cgn_i = NULL;
345345
}
346346

347+
/* Free RX table */
348+
kfree(phba->rxtable);
349+
phba->rxtable = NULL;
350+
347351
/* Free the iocb lookup array */
348352
kfree(psli->iocbq_lookup);
349353
psli->iocbq_lookup = NULL;

drivers/scsi/lpfc/lpfc_scsi.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3981,6 +3981,8 @@ lpfc_update_cmf_cmd(struct lpfc_hba *phba, uint32_t size)
39813981
atomic_inc(&phba->cmf_busy);
39823982
return -EBUSY;
39833983
}
3984+
if (size > atomic_read(&phba->rx_max_read_cnt))
3985+
atomic_set(&phba->rx_max_read_cnt, size);
39843986
}
39853987

39863988
cgs = this_cpu_ptr(phba->cmf_stat);

drivers/scsi/lpfc/lpfc_sli.c

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8068,6 +8068,21 @@ lpfc_cmf_setup(struct lpfc_hba *phba)
80688068
atomic64_set(&phba->cgn_latency_evt, 0);
80698069

80708070
phba->cmf_interval_rate = LPFC_CMF_INTERVAL;
8071+
8072+
/* Allocate RX Monitor Buffer */
8073+
if (!phba->rxtable) {
8074+
phba->rxtable = kmalloc_array(LPFC_MAX_RXMONITOR_ENTRY,
8075+
sizeof(struct rxtable_entry),
8076+
GFP_KERNEL);
8077+
if (!phba->rxtable) {
8078+
lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
8079+
"2644 Failed to alloc memory "
8080+
"for RX Monitor Buffer\n");
8081+
return -ENOMEM;
8082+
}
8083+
}
8084+
atomic_set(&phba->rxtable_idx_head, 0);
8085+
atomic_set(&phba->rxtable_idx_tail, 0);
80718086
return 0;
80728087
}
80738088

0 commit comments

Comments
 (0)