Skip to content

Commit f7e3935

Browse files
Quinn Trangregkh
Quinn Tran
authored andcommitted
scsi: qla2xxx: Move FCE Trace buffer allocation to user control
commit 841df27 upstream. Currently FCE Tracing is enabled to log additional ELS events. Instead, user will enable or disable this feature through debugfs. Modify existing DFS knob to allow user to enable or disable this feature. echo [1 | 0] > /sys/kernel/debug/qla2xxx/qla2xxx_??/fce cat /sys/kernel/debug/qla2xxx/qla2xxx_??/fce Cc: [email protected] Fixes: df613b9 ("[SCSI] qla2xxx: Add Fibre Channel Event (FCE) tracing support.") Signed-off-by: Quinn Tran <[email protected]> Signed-off-by: Nilesh Javali <[email protected]> Link: https://lore.kernel.org/r/[email protected] Reviewed-by: Himanshu Madhani <[email protected]> Signed-off-by: Martin K. Petersen <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent ca363c0 commit f7e3935

File tree

4 files changed

+126
-31
lines changed

4 files changed

+126
-31
lines changed

drivers/scsi/qla2xxx/qla_def.h

+2
Original file line numberDiff line numberDiff line change
@@ -4098,6 +4098,8 @@ struct qla_hw_data {
40984098
uint32_t npiv_supported :1;
40994099
uint32_t pci_channel_io_perm_failure :1;
41004100
uint32_t fce_enabled :1;
4101+
uint32_t user_enabled_fce :1;
4102+
uint32_t fce_dump_buf_alloced :1;
41014103
uint32_t fac_supported :1;
41024104

41034105
uint32_t chip_reset_done :1;

drivers/scsi/qla2xxx/qla_dfs.c

+102-22
Original file line numberDiff line numberDiff line change
@@ -409,26 +409,31 @@ qla2x00_dfs_fce_show(struct seq_file *s, void *unused)
409409

410410
mutex_lock(&ha->fce_mutex);
411411

412-
seq_puts(s, "FCE Trace Buffer\n");
413-
seq_printf(s, "In Pointer = %llx\n\n", (unsigned long long)ha->fce_wr);
414-
seq_printf(s, "Base = %llx\n\n", (unsigned long long) ha->fce_dma);
415-
seq_puts(s, "FCE Enable Registers\n");
416-
seq_printf(s, "%08x %08x %08x %08x %08x %08x\n",
417-
ha->fce_mb[0], ha->fce_mb[2], ha->fce_mb[3], ha->fce_mb[4],
418-
ha->fce_mb[5], ha->fce_mb[6]);
419-
420-
fce = (uint32_t *) ha->fce;
421-
fce_start = (unsigned long long) ha->fce_dma;
422-
for (cnt = 0; cnt < fce_calc_size(ha->fce_bufs) / 4; cnt++) {
423-
if (cnt % 8 == 0)
424-
seq_printf(s, "\n%llx: ",
425-
(unsigned long long)((cnt * 4) + fce_start));
426-
else
427-
seq_putc(s, ' ');
428-
seq_printf(s, "%08x", *fce++);
429-
}
412+
if (ha->flags.user_enabled_fce) {
413+
seq_puts(s, "FCE Trace Buffer\n");
414+
seq_printf(s, "In Pointer = %llx\n\n", (unsigned long long)ha->fce_wr);
415+
seq_printf(s, "Base = %llx\n\n", (unsigned long long)ha->fce_dma);
416+
seq_puts(s, "FCE Enable Registers\n");
417+
seq_printf(s, "%08x %08x %08x %08x %08x %08x\n",
418+
ha->fce_mb[0], ha->fce_mb[2], ha->fce_mb[3], ha->fce_mb[4],
419+
ha->fce_mb[5], ha->fce_mb[6]);
420+
421+
fce = (uint32_t *)ha->fce;
422+
fce_start = (unsigned long long)ha->fce_dma;
423+
for (cnt = 0; cnt < fce_calc_size(ha->fce_bufs) / 4; cnt++) {
424+
if (cnt % 8 == 0)
425+
seq_printf(s, "\n%llx: ",
426+
(unsigned long long)((cnt * 4) + fce_start));
427+
else
428+
seq_putc(s, ' ');
429+
seq_printf(s, "%08x", *fce++);
430+
}
430431

431-
seq_puts(s, "\nEnd\n");
432+
seq_puts(s, "\nEnd\n");
433+
} else {
434+
seq_puts(s, "FCE Trace is currently not enabled\n");
435+
seq_puts(s, "\techo [ 1 | 0 ] > fce\n");
436+
}
432437

433438
mutex_unlock(&ha->fce_mutex);
434439

@@ -467,7 +472,7 @@ qla2x00_dfs_fce_release(struct inode *inode, struct file *file)
467472
struct qla_hw_data *ha = vha->hw;
468473
int rval;
469474

470-
if (ha->flags.fce_enabled)
475+
if (ha->flags.fce_enabled || !ha->fce)
471476
goto out;
472477

473478
mutex_lock(&ha->fce_mutex);
@@ -488,11 +493,88 @@ qla2x00_dfs_fce_release(struct inode *inode, struct file *file)
488493
return single_release(inode, file);
489494
}
490495

496+
static ssize_t
497+
qla2x00_dfs_fce_write(struct file *file, const char __user *buffer,
498+
size_t count, loff_t *pos)
499+
{
500+
struct seq_file *s = file->private_data;
501+
struct scsi_qla_host *vha = s->private;
502+
struct qla_hw_data *ha = vha->hw;
503+
char *buf;
504+
int rc = 0;
505+
unsigned long enable;
506+
507+
if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha) &&
508+
!IS_QLA27XX(ha) && !IS_QLA28XX(ha)) {
509+
ql_dbg(ql_dbg_user, vha, 0xd034,
510+
"this adapter does not support FCE.");
511+
return -EINVAL;
512+
}
513+
514+
buf = memdup_user_nul(buffer, count);
515+
if (IS_ERR(buf)) {
516+
ql_dbg(ql_dbg_user, vha, 0xd037,
517+
"fail to copy user buffer.");
518+
return PTR_ERR(buf);
519+
}
520+
521+
enable = kstrtoul(buf, 0, 0);
522+
rc = count;
523+
524+
mutex_lock(&ha->fce_mutex);
525+
526+
if (enable) {
527+
if (ha->flags.user_enabled_fce) {
528+
mutex_unlock(&ha->fce_mutex);
529+
goto out_free;
530+
}
531+
ha->flags.user_enabled_fce = 1;
532+
if (!ha->fce) {
533+
rc = qla2x00_alloc_fce_trace(vha);
534+
if (rc) {
535+
ha->flags.user_enabled_fce = 0;
536+
mutex_unlock(&ha->fce_mutex);
537+
goto out_free;
538+
}
539+
540+
/* adjust fw dump buffer to take into account of this feature */
541+
if (!ha->flags.fce_dump_buf_alloced)
542+
qla2x00_alloc_fw_dump(vha);
543+
}
544+
545+
if (!ha->flags.fce_enabled)
546+
qla_enable_fce_trace(vha);
547+
548+
ql_dbg(ql_dbg_user, vha, 0xd045, "User enabled FCE .\n");
549+
} else {
550+
if (!ha->flags.user_enabled_fce) {
551+
mutex_unlock(&ha->fce_mutex);
552+
goto out_free;
553+
}
554+
ha->flags.user_enabled_fce = 0;
555+
if (ha->flags.fce_enabled) {
556+
qla2x00_disable_fce_trace(vha, NULL, NULL);
557+
ha->flags.fce_enabled = 0;
558+
}
559+
560+
qla2x00_free_fce_trace(ha);
561+
/* no need to re-adjust fw dump buffer */
562+
563+
ql_dbg(ql_dbg_user, vha, 0xd04f, "User disabled FCE .\n");
564+
}
565+
566+
mutex_unlock(&ha->fce_mutex);
567+
out_free:
568+
kfree(buf);
569+
return rc;
570+
}
571+
491572
static const struct file_operations dfs_fce_ops = {
492573
.open = qla2x00_dfs_fce_open,
493574
.read = seq_read,
494575
.llseek = seq_lseek,
495576
.release = qla2x00_dfs_fce_release,
577+
.write = qla2x00_dfs_fce_write,
496578
};
497579

498580
static int
@@ -626,8 +708,6 @@ qla2x00_dfs_setup(scsi_qla_host_t *vha)
626708
if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha) &&
627709
!IS_QLA27XX(ha) && !IS_QLA28XX(ha))
628710
goto out;
629-
if (!ha->fce)
630-
goto out;
631711

632712
if (qla2x00_dfs_root)
633713
goto create_dir;

drivers/scsi/qla2xxx/qla_gbl.h

+3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
/*
1212
* Global Function Prototypes in qla_init.c source file.
1313
*/
14+
int qla2x00_alloc_fce_trace(scsi_qla_host_t *);
15+
void qla2x00_free_fce_trace(struct qla_hw_data *ha);
16+
void qla_enable_fce_trace(scsi_qla_host_t *);
1417
extern int qla2x00_initialize_adapter(scsi_qla_host_t *);
1518
extern int qla24xx_post_prli_work(struct scsi_qla_host *vha, fc_port_t *fcport);
1619

drivers/scsi/qla2xxx/qla_init.c

+19-9
Original file line numberDiff line numberDiff line change
@@ -2681,7 +2681,7 @@ qla83xx_nic_core_fw_load(scsi_qla_host_t *vha)
26812681
return rval;
26822682
}
26832683

2684-
static void qla_enable_fce_trace(scsi_qla_host_t *vha)
2684+
void qla_enable_fce_trace(scsi_qla_host_t *vha)
26852685
{
26862686
int rval;
26872687
struct qla_hw_data *ha = vha->hw;
@@ -3717,25 +3717,24 @@ qla24xx_chip_diag(scsi_qla_host_t *vha)
37173717
return rval;
37183718
}
37193719

3720-
static void
3721-
qla2x00_alloc_fce_trace(scsi_qla_host_t *vha)
3720+
int qla2x00_alloc_fce_trace(scsi_qla_host_t *vha)
37223721
{
37233722
dma_addr_t tc_dma;
37243723
void *tc;
37253724
struct qla_hw_data *ha = vha->hw;
37263725

37273726
if (!IS_FWI2_CAPABLE(ha))
3728-
return;
3727+
return -EINVAL;
37293728

37303729
if (!IS_QLA25XX(ha) && !IS_QLA81XX(ha) && !IS_QLA83XX(ha) &&
37313730
!IS_QLA27XX(ha) && !IS_QLA28XX(ha))
3732-
return;
3731+
return -EINVAL;
37333732

37343733
if (ha->fce) {
37353734
ql_dbg(ql_dbg_init, vha, 0x00bd,
37363735
"%s: FCE Mem is already allocated.\n",
37373736
__func__);
3738-
return;
3737+
return -EIO;
37393738
}
37403739

37413740
/* Allocate memory for Fibre Channel Event Buffer. */
@@ -3745,7 +3744,7 @@ qla2x00_alloc_fce_trace(scsi_qla_host_t *vha)
37453744
ql_log(ql_log_warn, vha, 0x00be,
37463745
"Unable to allocate (%d KB) for FCE.\n",
37473746
FCE_SIZE / 1024);
3748-
return;
3747+
return -ENOMEM;
37493748
}
37503749

37513750
ql_dbg(ql_dbg_init, vha, 0x00c0,
@@ -3754,6 +3753,16 @@ qla2x00_alloc_fce_trace(scsi_qla_host_t *vha)
37543753
ha->fce_dma = tc_dma;
37553754
ha->fce = tc;
37563755
ha->fce_bufs = FCE_NUM_BUFFERS;
3756+
return 0;
3757+
}
3758+
3759+
void qla2x00_free_fce_trace(struct qla_hw_data *ha)
3760+
{
3761+
if (!ha->fce)
3762+
return;
3763+
dma_free_coherent(&ha->pdev->dev, FCE_SIZE, ha->fce, ha->fce_dma);
3764+
ha->fce = NULL;
3765+
ha->fce_dma = 0;
37573766
}
37583767

37593768
static void
@@ -3844,9 +3853,10 @@ qla2x00_alloc_fw_dump(scsi_qla_host_t *vha)
38443853
if (ha->tgt.atio_ring)
38453854
mq_size += ha->tgt.atio_q_length * sizeof(request_t);
38463855

3847-
qla2x00_alloc_fce_trace(vha);
3848-
if (ha->fce)
3856+
if (ha->fce) {
38493857
fce_size = sizeof(struct qla2xxx_fce_chain) + FCE_SIZE;
3858+
ha->flags.fce_dump_buf_alloced = 1;
3859+
}
38503860
qla2x00_alloc_eft_trace(vha);
38513861
if (ha->eft)
38523862
eft_size = EFT_SIZE;

0 commit comments

Comments
 (0)