Re: [PATCH] sd: make ->no_write_same independent of reported ->max_ws_blocks
Hello Martin, "Martin K. Petersen" writes: >> "Nicolai" == Nicolai Stange writes: > Nicolai> Due to reported problems with Write Same on ATA devices, commit > Nicolai> 0ce1b18c42a5 ("libata: Some drives failing on SCT Write Same") > Nicolai> strived to report non-support for Write Same on non-zoned ATA > Nicolai> devices. > > Nicolai> However, due to the following control flow in > Nicolai> sd_config_write_same() this doesn't always take effect, namely > Nicolai> if the ->max_ws_blocks as set in the by the ATA Identify Device > Nicolai> exceeds SD_WS10_BLOCKS: > > I'd much prefer for libata to set no_write_same = 1 for non-ZAC devices. Or just try it once and let the sd layer, i.e. sd_done(), disable it once a ILLEGAL COMMAND OPCODE is reported. This works right now and as you said below, calling code must cope gracefully with a failing Write Same anyway (which doesn't work right now). > > Older SCSI devices have no way to explicitly report that WRITE SAME is > supported. So the heuristic is the way it is to permit trying WRITE SAME > unless no_write_same has been set by the device driver. Ok, I didn't see that there might be a heuristic going on. I've got a couple of questions about this, but they're mainly out of curiosity. So feel free to ignore them. 1.) Do these older SCSI devices have a way to report ->max_ws_blocks? Because otherwise the heuristic would not work? Or is it set speculatively somewhere? 2.) If so, what about such older devices having 0 < ->max_ws_blocks < SD_MAX_WS10_BLOCKS ? Wouldn't these also be suitable candidates for trying that heuristic on? 3.) Those older devices that have ->max_ws_blocks > SD_MAX_WS10_BLOCKS but ->ws16 == ->ws10 == 0, i.e. the heuristicated ones would always be given WRITE_SAME, not WRITE_SAME_16 commands? C.f. sd_setup_write_same_cmnd(): if ->ws16 is not set, do WRITE_SAME. Isn't this a little bit odd given that the reported ->max_ws_blocks would be greater than SD_MAX_WS10_BLOCKS? Ok, given that these devices are older anyway, WRITE_SAME seems like the obvious choice to be made over WRITE_SAME_16. Which brings me back to question 2.). The answer to this question would possibly affect ATA devices with this heuristic going on as well: according to ata_scsiop_maint_in(), they would only support WRITE_SAME_16, but not WRITE_SAME. Heck, this is perhaps the reason why I'm seeing those errors this commit 0ce1b18c42a5 ("libata: Some drives failing on SCT Write Same") effectively turns the heuristics for my ATA device on, i.e. unsets ->ws16, resulting in WRITE_SAME's which are unsupported by libata-scsi, c.f. ata_get_xlat_func()... > > Nicolai> Since commit e73c23ff736e ("block: add async variant of > Nicolai> blkdev_issue_zeroout"), blkdev_issue_zeroout() got a little bit > Nicolai> more sensitive towards failing Write Sames on devices that > Nicolai> claim to support them and this results in messages like > > That's something that needs to be addressed. blkdev_issue_zeroout() must > cope with WRITE SAME failing and fall back to a manual zeroout. That's very useful information! So this commit really needs a fixup in either way. Thank you! Nicolai -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] scsi: avoid a permanent stop of the scsi device's request queue
A scan work can run simultaneously with fc_remote_port_delete(). If a scsi device is added to the ->__devices list in the scan work, it can be touched and will be blocked in scsi_target_block(), which will be called in fc_remote_port_delete(), and QUEUE_FLAG_STOPPED flag will be setted to the scsi device's request queue. The scsi device is being setted to the SDEV_RUNNING state at the end of the scan work. When the remote port reappears, scsi_target_unblock() will be called, but the QUEUE_FLAG_STOPPED flag will not be cleared, since scsi_internal_device_unblock() ignores SCSI devices in SDEV_RUNNING state. It results in a permanent stop of the scsi device's request queue. Every requests sended to it will be blocked. It looks like it's a regression caused by: commit 5c10e63c943b ("[SCSI] limit state transitions in scsi_internal_device_unblock") Fix this by restarting the device queue if the state is SDEV_RUNNING. Reported-by: Zengxi Chen Signed-off-by: Wei Fang --- drivers/scsi/scsi_lib.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 9ca1f17..253ee74 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c @@ -2942,7 +2942,8 @@ scsi_internal_device_unblock(struct scsi_device *sdev, else sdev->sdev_state = SDEV_CREATED; } else if (sdev->sdev_state != SDEV_CANCEL && -sdev->sdev_state != SDEV_OFFLINE) +sdev->sdev_state != SDEV_OFFLINE && +sdev->sdev_state != SDEV_RUNNING) return -EINVAL; if (q->mq_ops) { -- 2.4.11 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: scsi: use-after-free in bio_copy_from_iter
On Mon, Dec 05, 2016 at 07:03:39PM +, Al Viro wrote: > On Mon, Dec 05, 2016 at 04:17:53PM +0100, Johannes Thumshirn wrote: > > 633 hp = &srp->header; > > [...] > > 646 hp->dxferp = (char __user *)buf + cmd_size; > > > So the memory for hp->dxferp comes from: > > 633 hp = &srp->header; > > > > > >From my debug instrumentation I see that the dxferp ends up in the > > iovec_iter's kvec->iov_base and the faulting address is always dxferp + n * > > 4k with n in [1, 16] (and we're copying 16 4k pages from the iovec into the > > bio). > > _Address_ of hp->dxferp comes from that assignment; the value is 'buf' > argument of sg_write() + small offset. In this case, it should point > inside a pipe buffer, which is, indeed, at a kernel address. Who'd > allocated srp is irrelevant. Yes I realized that as well when I had enough distance between me and the code... > > And if you end up dereferencing more than one page worth there, you do have > a problem - pipe buffers are not going to be that large. Could you slap > WARN_ON((size_t)input_size > count); > right after the calculation of input_size in sg_write() and see if it triggers > on your reproducer? I did and it didn't trigger. What triggers is (as expected) a WARN_ON((size_t)mxsize > count); We have count at 80 and mxsize (which ends in hp->dxfer_len) at 65499. But the 65499 bytes are the len of the data we're suppost to be copying in via the iov. I'm still rather confused what's happening here, sorry. -- Johannes Thumshirn Storage jthumsh...@suse.de+49 911 74053 689 SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: Felix Imendörffer, Jane Smithard, Graham Norton HRB 21284 (AG Nürnberg) Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: scsi: use-after-free in bio_copy_from_iter
On Tue, Dec 6, 2016 at 10:32 AM, Johannes Thumshirn wrote: > On Mon, Dec 05, 2016 at 07:03:39PM +, Al Viro wrote: >> On Mon, Dec 05, 2016 at 04:17:53PM +0100, Johannes Thumshirn wrote: >> > 633 hp = &srp->header; >> > [...] >> > 646 hp->dxferp = (char __user *)buf + cmd_size; >> >> > So the memory for hp->dxferp comes from: >> > 633 hp = &srp->header; >> >> >> >> > >From my debug instrumentation I see that the dxferp ends up in the >> > iovec_iter's kvec->iov_base and the faulting address is always dxferp + n * >> > 4k with n in [1, 16] (and we're copying 16 4k pages from the iovec into the >> > bio). >> >> _Address_ of hp->dxferp comes from that assignment; the value is 'buf' >> argument of sg_write() + small offset. In this case, it should point >> inside a pipe buffer, which is, indeed, at a kernel address. Who'd >> allocated srp is irrelevant. > > Yes I realized that as well when I had enough distance between me and the > code... > >> >> And if you end up dereferencing more than one page worth there, you do have >> a problem - pipe buffers are not going to be that large. Could you slap >> WARN_ON((size_t)input_size > count); >> right after the calculation of input_size in sg_write() and see if it >> triggers >> on your reproducer? > > I did and it didn't trigger. What triggers is (as expected) a > WARN_ON((size_t)mxsize > count); > We have count at 80 and mxsize (which ends in hp->dxfer_len) at 65499. But the > 65499 bytes are the len of the data we're suppost to be copying in via the > iov. I'm still rather confused what's happening here, sorry. I think the critical piece here is some kind of race or timing condition. Note that the test program executes all of memfd_create/write/open/sendfile twice. Second time the calls race with each other, but they also can race with the first execution of the calls. -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] xen-scsifront: Add a missing call to kfree
Oops. Sorry for the noise. regards, dan carpenter -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] qla4xxx: switch to pci_alloc_irq_vectors
Please see comments inline. Thanks, Nilesh On 18/11/16, 12:45 PM, "Christoph Hellwig" wrote: >And simplify the MSI-X logic in general - just request the two >vectors directly instead of going through an indirection table. > >Signed-off-by: Christoph Hellwig >--- > drivers/scsi/qla4xxx/ql4_def.h | 18 + > drivers/scsi/qla4xxx/ql4_glbl.h | 1 - > drivers/scsi/qla4xxx/ql4_isr.c | 25 +--- > drivers/scsi/qla4xxx/ql4_nx.c | 87 >+++-- > 4 files changed, 35 insertions(+), 96 deletions(-) > >diff --git a/drivers/scsi/qla4xxx/ql4_def.h >b/drivers/scsi/qla4xxx/ql4_def.h >index a7cfc27..aeebefb 100644 >--- a/drivers/scsi/qla4xxx/ql4_def.h >+++ b/drivers/scsi/qla4xxx/ql4_def.h >@@ -409,18 +409,9 @@ struct qla4_8xxx_legacy_intr_set { > > /* MSI-X Support */ > >-#define QLA_MSIX_DEFAULT 0x00 >-#define QLA_MSIX_RSP_Q0x01 >- >+#define QLA_MSIX_DEFAULT 0 >+#define QLA_MSIX_RSP_Q1 > #define QLA_MSIX_ENTRIES 2 >-#define QLA_MIDX_DEFAULT 0 >-#define QLA_MIDX_RSP_Q1 >- >-struct ql4_msix_entry { >- int have_irq; >- uint16_t msix_vector; >- uint16_t msix_entry; >-}; > > /* > * ISP Operations >@@ -572,9 +563,6 @@ struct scsi_qla_host { > #define AF_IRQ_ATTACHED 10 /* 0x0400 */ > #define AF_DISABLE_ACB_COMPLETE 11 /* 0x0800 */ > #define AF_HA_REMOVAL 12 /* 0x1000 */ >-#define AF_INTx_ENABLED 15 /* 0x8000 */ >-#define AF_MSI_ENABLED16 /* 0x0001 */ >-#define AF_MSIX_ENABLED 17 /* 0x0002 */ > #define AF_MBOX_COMMAND_NOPOLL18 /* 0x0004 */ > #define AF_FW_RECOVERY19 /* 0x0008 */ > #define AF_EEH_BUSY 20 /* 0x0010 */ >@@ -762,8 +750,6 @@ struct scsi_qla_host { > struct isp_operations *isp_ops; > struct ql82xx_hw_data hw; > >- struct ql4_msix_entry msix_entries[QLA_MSIX_ENTRIES]; >- > uint32_t nx_dev_init_timeout; > uint32_t nx_reset_timeout; > void *fw_dump; >diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h >b/drivers/scsi/qla4xxx/ql4_glbl.h >index 2559144..bce96a5 100644 >--- a/drivers/scsi/qla4xxx/ql4_glbl.h >+++ b/drivers/scsi/qla4xxx/ql4_glbl.h >@@ -134,7 +134,6 @@ int qla4_8xxx_get_flash_info(struct scsi_qla_host >*ha); > void qla4_82xx_enable_intrs(struct scsi_qla_host *ha); > void qla4_82xx_disable_intrs(struct scsi_qla_host *ha); > int qla4_8xxx_enable_msix(struct scsi_qla_host *ha); >-void qla4_8xxx_disable_msix(struct scsi_qla_host *ha); > irqreturn_t qla4_8xxx_msi_handler(int irq, void *dev_id); > irqreturn_t qla4_8xxx_default_intr_handler(int irq, void *dev_id); > irqreturn_t qla4_8xxx_msix_rsp_q(int irq, void *dev_id); >diff --git a/drivers/scsi/qla4xxx/ql4_isr.c >b/drivers/scsi/qla4xxx/ql4_isr.c >index 4f9c0f2..ff89bba 100644 >--- a/drivers/scsi/qla4xxx/ql4_isr.c >+++ b/drivers/scsi/qla4xxx/ql4_isr.c >@@ -1107,7 +1107,7 @@ static void qla4_82xx_spurious_interrupt(struct >scsi_qla_host *ha, > DEBUG2(ql4_printk(KERN_INFO, ha, "Spurious Interrupt\n")); > if (is_qla8022(ha)) { > writel(0, &ha->qla4_82xx_reg->host_int); >- if (test_bit(AF_INTx_ENABLED, &ha->flags)) >+ if (!ha->pdev->msi_enabled && !ha->pdev->msix_enabled) > qla4_82xx_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, > 0xfbff); > } >@@ -1564,19 +1564,18 @@ int qla4xxx_request_irqs(struct scsi_qla_host *ha) > > try_msi: > /* Trying MSI */ >- ret = pci_enable_msi(ha->pdev); >+ ret = pci_alloc_irq_vectors(ha->pdev, 1, 1, PCI_IRQ_MSI); > if (!ret) { Since pci_alloc_irq_vectors returns a negative error code upon error, This should be if (ret). > ret = request_irq(ha->pdev->irq, qla4_8xxx_msi_handler, > 0, DRIVER_NAME, ha); > if (!ret) { > DEBUG2(ql4_printk(KERN_INFO, ha, "MSI: Enabled.\n")); >- set_bit(AF_MSI_ENABLED, &ha->flags); > goto irq_attached; > } else { > ql4_printk(KERN_WARNING, ha, > "MSI: Failed to reserve interrupt %d " > "already in use.\n", ha->pdev->irq); >- pci_disable_msi(ha->pdev); >+ pci_free_irq_vectors(ha->pdev); > } > } > >@@ -1592,7 +1591,6 @@ int qla4xxx_request_irqs(struct scsi_qla_host *ha) > IRQF_SHARED, DRIVER_NAME, ha); > if (!ret) { > DEBUG2(ql4_printk(KERN_INFO, ha, "INTx: Enabled.\n")); >- set_bit(AF_INTx_ENABLED, &ha->flags); > goto irq_attached; > > } else { >@@ -1614,14 +1612,11 @@ int qla4xxx_request_irqs(struct scsi_qla_host *ha) > > void qla4xxx_free_irqs(struct scsi_qla_host *ha) > { >- if (t
[PATCH] scsi: hisi_sas: support deferred probe for v2 hw
In the hip06 and hip07 SoCs, the interrupt lines from the SAS controllers are connected to mbigen hw module [1]. The mbigen module is probed with module_init, and, as such, is not guaranteed to probe before the SAS driver. So we need to support deferred probe. We check for probe deferral in the hw layer probe, so we not probe into the main layer and allocate shost, memories, etc., to later learn that we need to defer the probe. [1] ./Documentation/devicetree/bindings/interrupt-controller/hisilicon,mbigen-v2.txt Signed-off-by: John Garry diff --git a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c index c0e7bf2..a179592 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v2_hw.c @@ -2971,6 +2971,18 @@ static int hisi_sas_v2_init(struct hisi_hba *hisi_hba) static int hisi_sas_v2_probe(struct platform_device *pdev) { + /* +* Check if we should defer the probe before we probe the +* upper layer, as it's hard to defer later on. +*/ + int ret = platform_get_irq(pdev, 0); + + if (ret < 0) { + if (ret != -EPROBE_DEFER) + dev_err(&pdev->dev, "cannot obtain irq\n"); + return ret; + } + return hisi_sas_probe(pdev, &hisi_sas_v2_hw); } -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] scsi: mvsas: Replace pci_pool_alloc by pci_pool_zalloc
Hi Martin, On Tue, Dec 6, 2016 at 3:34 AM, Martin K. Petersen wrote: >> "Souptick" == Souptick Joarder writes: > > Souptick, > > Souptick> Any comment on this patch? > > The patch looked OK to me when you posted it. However, you need one > person in addition to me to review it. And you need convince us of the > merit of a presumably untested change to an unmaintained driver. pci_pool_zalloc() will perform the same as pci_pool_alloc() and memset combined. I have send similar patches to other modules like - dmaengine, scsi, net, gpu . Those were accepted and merged into respective branches. one similar patch you have applied previously. I am sure this patch will work fine even without testing. > > -- > Martin K. Petersen Oracle Linux Engineering Regards Souptick -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] scsi: mvsas: Replace pci_pool_alloc by pci_pool_zalloc
On Mon, Nov 28, 2016 at 04:56:26PM +0530, Souptick Joarder wrote: > Inside mvs_task_prep(), pci_pool_alloc() followed by memset will be > replaced by pci_pool_zalloc() > > Signed-off-by: Souptick joarder > --- FWIW, Reviewed-by: Johannes Thumshirn -- Johannes Thumshirn Storage jthumsh...@suse.de+49 911 74053 689 SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: Felix Imendörffer, Jane Smithard, Graham Norton HRB 21284 (AG Nürnberg) Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
RE: [PATCH] megaraid_sas: switch to pci_alloc_irq_vectors
>-Original Message- >From: linux-scsi-ow...@vger.kernel.org [mailto:linux-scsi- >ow...@vger.kernel.org] On Behalf Of Hannes Reinecke >Sent: Friday, December 02, 2016 5:22 PM >To: Martin K. Petersen >Cc: Christoph Hellwig; James Bottomley; Sathya Prakash; linux- >s...@vger.kernel.org; Hannes Reinecke; Hannes Reinecke >Subject: [PATCH] megaraid_sas: switch to pci_alloc_irq_vectors > >Signed-off-by: Hannes Reinecke >--- > drivers/scsi/megaraid/megaraid_sas.h | 1 - > drivers/scsi/megaraid/megaraid_sas_base.c | 78 +++ > 2 files changed, 38 insertions(+), 41 deletions(-) > >diff --git a/drivers/scsi/megaraid/megaraid_sas.h >b/drivers/scsi/megaraid/megaraid_sas.h >index 74c7b44..757ddda 100644 >--- a/drivers/scsi/megaraid/megaraid_sas.h >+++ b/drivers/scsi/megaraid/megaraid_sas.h >@@ -2120,7 +2120,6 @@ struct megasas_instance { > u32 ctrl_context_pages; > struct megasas_ctrl_info *ctrl_info; > unsigned int msix_vectors; >- struct msix_entry msixentry[MEGASAS_MAX_MSIX_QUEUES]; > struct megasas_irq_context >irq_context[MEGASAS_MAX_MSIX_QUEUES]; > u64 map_id; > u64 pd_seq_map_id; >diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c >b/drivers/scsi/megaraid/megaraid_sas_base.c >index 5462676..692f40a 100644 >--- a/drivers/scsi/megaraid/megaraid_sas_base.c >+++ b/drivers/scsi/megaraid/megaraid_sas_base.c >@@ -4837,7 +4837,7 @@ int megasas_set_crash_dump_params(struct >megasas_instance *instance, } > > /* >- * megasas_setup_irqs_msix - register legacy interrupts. >+ * megasas_setup_irqs_ioapic -register legacy interrupts. > * @instance: Adapter soft state > * > * Do not enable interrupt, only setup ISRs. >@@ -4852,8 +4852,9 @@ int megasas_set_crash_dump_params(struct >megasas_instance *instance, > pdev = instance->pdev; > instance->irq_context[0].instance = instance; > instance->irq_context[0].MSIxIndex = 0; >- if (request_irq(pdev->irq, instance->instancet->service_isr, >- IRQF_SHARED, "megasas", &instance->irq_context[0])) { >+ if (request_irq(pci_irq_vector(pdev, 0), >+ instance->instancet->service_isr, IRQF_SHARED, >+ "megasas", &instance->irq_context[0])) { > dev_err(&instance->pdev->dev, > "Failed to register IRQ from %s %d\n", > __func__, __LINE__); >@@ -4874,28 +4875,23 @@ int megasas_set_crash_dump_params(struct >megasas_instance *instance, static int megasas_setup_irqs_msix(struct >megasas_instance *instance, u8 is_probe) { >- int i, j, cpu; >+ int i, j; > struct pci_dev *pdev; > > pdev = instance->pdev; > > /* Try MSI-x */ >- cpu = cpumask_first(cpu_online_mask); > for (i = 0; i < instance->msix_vectors; i++) { > instance->irq_context[i].instance = instance; > instance->irq_context[i].MSIxIndex = i; >- if (request_irq(instance->msixentry[i].vector, >+ if (request_irq(pci_irq_vector(pdev, i), > instance->instancet->service_isr, 0, "megasas", > &instance->irq_context[i])) { > dev_err(&instance->pdev->dev, > "Failed to register IRQ for vector %d.\n", i); >- for (j = 0; j < i; j++) { >- if (smp_affinity_enable) >- irq_set_affinity_hint( >- instance->msixentry[j].vector, >NULL); >- free_irq(instance->msixentry[j].vector, >- &instance->irq_context[j]); >- } >+ for (j = 0; j < i; j++) >+ free_irq(pci_irq_vector(pdev, j), >+ &instance->irq_context[j]); > /* Retry irq register for IO_APIC*/ > instance->msix_vectors = 0; > if (is_probe) >@@ -4903,14 +4899,6 @@ int megasas_set_crash_dump_params(struct >megasas_instance *instance, > else > return -1; > } >- if (smp_affinity_enable) { >- if (irq_set_affinity_hint(instance->msixentry[i].vector, >- get_cpu_mask(cpu))) >- dev_err(&instance->pdev->dev, >- "Failed to set affinity hint" >- " for cpu %d\n", cpu); >- cpu = cpumask_next(cpu, cpu_online_mask); >- } > } > return 0; > } >@@ -4927,14 +4915,12 @@ int megasas_set_crash_dump_params(struct >megasas_instance *instance, > > if (instance->msix_vectors) > for (i = 0; i < instance->msix_vectors; i++) { >- if (sm
Re: [PATCH] qla4xxx: switch to pci_alloc_irq_vectors
Hi Nilesh, > > try_msi: > > /* Trying MSI */ > >-ret = pci_enable_msi(ha->pdev); > >+ret = pci_alloc_irq_vectors(ha->pdev, 1, 1, PCI_IRQ_MSI); > > if (!ret) { > > Since pci_alloc_irq_vectors returns a negative error code upon error, > This should be if (ret). Fixes, thanks. > Similarly, driver load fails here as pci_alloc_irq_vectors returns correct > num of vectors. > Hence this should be, if (ret < 0). Also fixed. The new version is on it's way. -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2] qla4xxx: switch to pci_alloc_irq_vectors
And simplify the MSI-X logic in general - just request the two vectors directly instead of going through an indirection table. Signed-off-by: Christoph Hellwig --- drivers/scsi/qla4xxx/ql4_def.h | 18 + drivers/scsi/qla4xxx/ql4_glbl.h | 1 - drivers/scsi/qla4xxx/ql4_isr.c | 27 + drivers/scsi/qla4xxx/ql4_nx.c | 89 +++-- 4 files changed, 37 insertions(+), 98 deletions(-) diff --git a/drivers/scsi/qla4xxx/ql4_def.h b/drivers/scsi/qla4xxx/ql4_def.h index a7cfc27..aeebefb 100644 --- a/drivers/scsi/qla4xxx/ql4_def.h +++ b/drivers/scsi/qla4xxx/ql4_def.h @@ -409,18 +409,9 @@ struct qla4_8xxx_legacy_intr_set { /* MSI-X Support */ -#define QLA_MSIX_DEFAULT 0x00 -#define QLA_MSIX_RSP_Q 0x01 - +#define QLA_MSIX_DEFAULT 0 +#define QLA_MSIX_RSP_Q 1 #define QLA_MSIX_ENTRIES 2 -#define QLA_MIDX_DEFAULT 0 -#define QLA_MIDX_RSP_Q 1 - -struct ql4_msix_entry { - int have_irq; - uint16_t msix_vector; - uint16_t msix_entry; -}; /* * ISP Operations @@ -572,9 +563,6 @@ struct scsi_qla_host { #define AF_IRQ_ATTACHED10 /* 0x0400 */ #define AF_DISABLE_ACB_COMPLETE11 /* 0x0800 */ #define AF_HA_REMOVAL 12 /* 0x1000 */ -#define AF_INTx_ENABLED15 /* 0x8000 */ -#define AF_MSI_ENABLED 16 /* 0x0001 */ -#define AF_MSIX_ENABLED17 /* 0x0002 */ #define AF_MBOX_COMMAND_NOPOLL 18 /* 0x0004 */ #define AF_FW_RECOVERY 19 /* 0x0008 */ #define AF_EEH_BUSY20 /* 0x0010 */ @@ -762,8 +750,6 @@ struct scsi_qla_host { struct isp_operations *isp_ops; struct ql82xx_hw_data hw; - struct ql4_msix_entry msix_entries[QLA_MSIX_ENTRIES]; - uint32_t nx_dev_init_timeout; uint32_t nx_reset_timeout; void *fw_dump; diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h b/drivers/scsi/qla4xxx/ql4_glbl.h index 2559144..bce96a5 100644 --- a/drivers/scsi/qla4xxx/ql4_glbl.h +++ b/drivers/scsi/qla4xxx/ql4_glbl.h @@ -134,7 +134,6 @@ int qla4_8xxx_get_flash_info(struct scsi_qla_host *ha); void qla4_82xx_enable_intrs(struct scsi_qla_host *ha); void qla4_82xx_disable_intrs(struct scsi_qla_host *ha); int qla4_8xxx_enable_msix(struct scsi_qla_host *ha); -void qla4_8xxx_disable_msix(struct scsi_qla_host *ha); irqreturn_t qla4_8xxx_msi_handler(int irq, void *dev_id); irqreturn_t qla4_8xxx_default_intr_handler(int irq, void *dev_id); irqreturn_t qla4_8xxx_msix_rsp_q(int irq, void *dev_id); diff --git a/drivers/scsi/qla4xxx/ql4_isr.c b/drivers/scsi/qla4xxx/ql4_isr.c index 4f9c0f2..d2cd33d 100644 --- a/drivers/scsi/qla4xxx/ql4_isr.c +++ b/drivers/scsi/qla4xxx/ql4_isr.c @@ -1107,7 +1107,7 @@ static void qla4_82xx_spurious_interrupt(struct scsi_qla_host *ha, DEBUG2(ql4_printk(KERN_INFO, ha, "Spurious Interrupt\n")); if (is_qla8022(ha)) { writel(0, &ha->qla4_82xx_reg->host_int); - if (test_bit(AF_INTx_ENABLED, &ha->flags)) + if (!ha->pdev->msi_enabled && !ha->pdev->msix_enabled) qla4_82xx_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, 0xfbff); } @@ -1564,19 +1564,18 @@ int qla4xxx_request_irqs(struct scsi_qla_host *ha) try_msi: /* Trying MSI */ - ret = pci_enable_msi(ha->pdev); - if (!ret) { + ret = pci_alloc_irq_vectors(ha->pdev, 1, 1, PCI_IRQ_MSI); + if (ret > 0) { ret = request_irq(ha->pdev->irq, qla4_8xxx_msi_handler, 0, DRIVER_NAME, ha); if (!ret) { DEBUG2(ql4_printk(KERN_INFO, ha, "MSI: Enabled.\n")); - set_bit(AF_MSI_ENABLED, &ha->flags); goto irq_attached; } else { ql4_printk(KERN_WARNING, ha, "MSI: Failed to reserve interrupt %d " "already in use.\n", ha->pdev->irq); - pci_disable_msi(ha->pdev); + pci_free_irq_vectors(ha->pdev); } } @@ -1592,7 +1591,6 @@ int qla4xxx_request_irqs(struct scsi_qla_host *ha) IRQF_SHARED, DRIVER_NAME, ha); if (!ret) { DEBUG2(ql4_printk(KERN_INFO, ha, "INTx: Enabled.\n")); - set_bit(AF_INTx_ENABLED, &ha->flags); goto irq_attached; } else { @@ -1614,14 +1612,11 @@ int qla4xxx_request_irqs(struct scsi_qla_host *ha) void qla4xxx_free_irqs(struct scsi_qla_host *ha) { - if (test_and_clear_bit(AF_IRQ_ATTACHED, &ha->flags)) { - if (test_bit(AF_MSIX_ENABLED, &ha->flags)) { - qla4_8xxx_disable_msix(ha); - } else if (test_and_clear_bit(AF_MSI_ENABLED, &ha->flags)) { - free_irq(ha->pde
Re: [PATCH v3 1/6] qla2xxx: Only allow operational MBX to proceed during RESET.
Thanks, please update the patch with this description for next resend. -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: HD is powered off too early during shutdown/reboot (4.8 regression?)
Hi, just FYI, obviously my issue was related to kernel bug #187061 [1]. I did a test build of kernel 4.8.12 with the patch from the bug report applied and this resolved the issue for me. So, I’m voting for a backport of this change to kernel 4.8. If this is the wrong place to ask for a backport, please excuse me, I’m still new here. I’d be grateful if you could point me to the right place in this case. Best, and sorry for the noise, Johannes [1] https://bugzilla.kernel.org/show_bug.cgi?id=187061 > Am 24.11.2016 um 18:24 schrieb Johannes Maibaum : > > Hi, > > this is my first posting on a Linux kernel related list, and I hope that > this is the correct place. If not, I'd be glad if you could point me to > the right place. People on the Arch Linux forums [1] and on the > systemd-devel mailing list [2] suggested to report this issue to the > kernel community. > > I try to be as specific as I can, but unfortunately I'm not a low-level > Linux expert. > > Since installing kernel 4.8, I have a problem with my MacBook Pro > running Arch Linux on a second HD installed in a HD caddy [1]. The root > and /home file systems are on this HD (/dev/sdb, see below), while /boot > is on the first HD alongside macOS (/dev/sda). > > On shutdown/reboot, it seems that the HD (or the caddy?) gets powered > off too early, which is clearly audible ('clank!'). Shortly afterwards, > the following errors appears on screen (transcribed from a photo): > > ata2: exception Emask 0x10 SAct 0x0 SErr 0x199 action 0xe > frozenbd204ed5c > ata2: irq_stat 0x0040, PHY RDY changed > ata2: SError: { PHYRdyChg 10B8B Dispar LinkSeq TrStaTrns } > > The machine shuts down or reboots a few seconds later, but I've never > seen the above errors on another kernel before (kernel 4.4 through 4.7 > were installed on this machine and all worked OK), so it seems to be a > regression. > > Unfortunately, I haven't yet succeeded in gathering more verbose debug > information from late shutdown. I tried to follow the guide in the > systemd docs [4], but the script failed (probably, since the hd is > already gone when the script tries to run). But I will happily try to > provide you with more information if needed. > > Here's some more information about my setup: > > $ dmesg | grep ata2 | head > [2.508533] ata2: SATA max UDMA/133 abar m8192@0xd3484000 port > 0xd3484180 irq 26 > [2.824504] ata2: SATA link up 1.5 Gbps (SStatus 113 SControl 300) > [2.825383] ata2.00: ACPI cmd ef/10:03:00:00:00:a0 (SET FEATURES) > filtered out > [2.825543] ata2.00: ATA-8: Hitachi HTS545032B9SA02, PB3AC60W, max > UDMA/133 > [2.825545] ata2.00: 625142448 sectors, multi 0: LBA48 NCQ (depth 31/32) > [2.826577] ata2.00: ACPI cmd ef/10:03:00:00:00:a0 (SET FEATURES) > filtered out > [2.826745] ata2.00: configured for UDMA/133 > $ readlink /dev/disk/by-id/*HTS545032B9SA02* | head -n1 > ../../sdb > $ lsblk > NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT > sdb 8:16 0 298,1G 0 disk > ├─sdb2 8:18 0 268,1G 0 part /home > └─sdb1 8:17 030G 0 part / > sda 8:00 931,5G 0 disk > ├─sda2 8:20 930,7G 0 part > ├─sda3 8:30 619,9M 0 part > └─sda1 8:10 200M 0 part /boot > > > Best, > Johannes > > [1] Here's a link to the HD caddy: https://www.amazon.com/dp/B0090KFOYS > [2] Arch Linux forum thread: > https://bbs.archlinux.org/viewtopic.php?pid=1668277 > [3] Systemd-devel thread: > https://lists.freedesktop.org/archives/systemd-devel/2016-November/037882.html > [4] https://freedesktop.org/wiki/Software/systemd/Debugging/#index2h1 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH RESEND v2 1/2] blk-mq: Fix failed allocation path when mapping queues
In blk_mq_map_swqueue, there is a memory optimization that frees the tags of a queue that has gone unmapped. Later, if that hctx is remapped after another topology change, the tags need to be reallocated. If this allocation fails, a simple WARN_ON triggers, but the block layer ends up with an active hctx without any corresponding set of tags. Then, any income IO to that hctx can trigger an Oops. I can reproduce it consistently by running IO, flipping CPUs on and off and eventually injecting a memory allocation failure in that path. In the fix below, if the system experiences a failed allocation of any hctx's tags, we remap all the ctxs of that queue to the hctx_0, which should always keep it's tags. There is a minor performance hit, since our mapping just got worse after the error path, but this is the simplest solution to handle this error path. The performance hit will disappear after another successful remap. I considered dropping the memory optimization all together, but it seemed a bad trade-off to handle this very specific error case. This should apply cleanly on top of Jen's for-next branch. The Oops is the one below: SP (3fff935ce4d0) is in userspace 1:mon> e cpu 0x1: Vector: 300 (Data Access) at [c00fe99eb110] pc: c05e868c: __sbitmap_queue_get+0x2c/0x180 lr: c0575328: __bt_get+0x48/0xd0 sp: c00fe99eb390 msr: 90010280b033 dar: 28 dsisr: 4000 current = 0xc00fe9966800 paca= 0xc7e80300 softe: 0irq_happened: 0x01 pid = 11035, comm = aio-stress Linux version 4.8.0-rc6+ (root@bean) (gcc version 5.4.0 20160609 (Ubuntu/IBM 5.4.0-6ubuntu1~16.04.2) ) #3 SMP Mon Oct 10 20:16:53 CDT 2016 1:mon> s [c00fe99eb3d0] c0575328 __bt_get+0x48/0xd0 [c00fe99eb400] c0575838 bt_get.isra.1+0x78/0x2d0 [c00fe99eb480] c0575cb4 blk_mq_get_tag+0x44/0x100 [c00fe99eb4b0] c056f6f4 __blk_mq_alloc_request+0x44/0x220 [c00fe99eb500] c0570050 blk_mq_map_request+0x100/0x1f0 [c00fe99eb580] c0574650 blk_mq_make_request+0xf0/0x540 [c00fe99eb640] c0561c44 generic_make_request+0x144/0x230 [c00fe99eb690] c0561e00 submit_bio+0xd0/0x200 [c00fe99eb740] c03ef740 ext4_io_submit+0x90/0xb0 [c00fe99eb770] c03e95d8 ext4_writepages+0x588/0xdd0 [c00fe99eb910] c025a9f0 do_writepages+0x60/0xc0 [c00fe99eb940] c0246c88 __filemap_fdatawrite_range+0xf8/0x180 [c00fe99eb9e0] c0246f90 filemap_write_and_wait_range+0x70/0xf0 [c00fe99eba20] c03dd844 ext4_sync_file+0x214/0x540 [c00fe99eba80] c0364718 vfs_fsync_range+0x78/0x130 [c00fe99ebad0] c03dd46c ext4_file_write_iter+0x35c/0x430 [c00fe99ebb90] c038c280 aio_run_iocb+0x3b0/0x450 [c00fe99ebce0] c038dc28 do_io_submit+0x368/0x730 [c00fe99ebe30] c0009404 system_call+0x38/0xec Signed-off-by: Gabriel Krisman Bertazi Cc: Brian King Cc: Douglas Miller Cc: linux-bl...@vger.kernel.org Cc: linux-scsi@vger.kernel.org --- block/blk-mq.c | 21 +++-- 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/block/blk-mq.c b/block/blk-mq.c index 6fb94bd69375..6718f894fbe1 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -1870,7 +1870,7 @@ static void blk_mq_init_cpu_queues(struct request_queue *q, static void blk_mq_map_swqueue(struct request_queue *q, const struct cpumask *online_mask) { - unsigned int i; + unsigned int i, hctx_idx; struct blk_mq_hw_ctx *hctx; struct blk_mq_ctx *ctx; struct blk_mq_tag_set *set = q->tag_set; @@ -1893,6 +1893,15 @@ static void blk_mq_map_swqueue(struct request_queue *q, if (!cpumask_test_cpu(i, online_mask)) continue; + hctx_idx = q->mq_map[i]; + /* unmapped hw queue can be remapped after CPU topo changed */ + if (!set->tags[hctx_idx]) { + set->tags[hctx_idx] = blk_mq_init_rq_map(set, hctx_idx); + + if (!set->tags[hctx_idx]) + q->mq_map[i] = 0; + } + ctx = per_cpu_ptr(q->queue_ctx, i); hctx = blk_mq_map_queue(q, i); @@ -1909,7 +1918,10 @@ static void blk_mq_map_swqueue(struct request_queue *q, * disable it and free the request entries. */ if (!hctx->nr_ctx) { - if (set->tags[i]) { + /* Never unmap queue 0. We need it as a +* fallback in case of a new remap fails +* allocation. */ + if (i && set->tags[i]) { blk_mq_free_rq_map(set, set->tags[i], i); set->tags[i] = NULL; } @@ -1917,11 +1929,8 @@ static void blk_mq_map_swqueue(struct re
[PATCH RESEND v2 2/2] blk-mq: Avoid memory reclaim when remapping queues
While stressing memory and IO at the same time we changed SMT settings, we were able to consistently trigger deadlocks in the mm system, which froze the entire machine. I think that under memory stress conditions, the large allocations performed by blk_mq_init_rq_map may trigger a reclaim, which stalls waiting on the block layer remmaping completion, thus deadlocking the system. The trace below was collected after the machine stalled, waiting for the hotplug event completion. The simplest fix for this is to make allocations in this path non-reclaimable, with GFP_NOIO. With this patch, We couldn't hit the issue anymore. This should apply on top of Jen's for-next branch cleanly. Changes since v1: - Use GFP_NOIO instead of GFP_NOWAIT. Call Trace: [c00f0160aaf0] [c00f0160ab50] 0xc00f0160ab50 (unreliable) [c00f0160acc0] [c0016624] __switch_to+0x2e4/0x430 [c00f0160ad20] [c0b1a880] __schedule+0x310/0x9b0 [c00f0160ae00] [c0b1af68] schedule+0x48/0xc0 [c00f0160ae30] [c0b1b4b0] schedule_preempt_disabled+0x20/0x30 [c00f0160ae50] [c0b1d4fc] __mutex_lock_slowpath+0xec/0x1f0 [c00f0160aed0] [c0b1d678] mutex_lock+0x78/0xa0 [c00f0160af00] [d00019413cac] xfs_reclaim_inodes_ag+0x33c/0x380 [xfs] [c00f0160b0b0] [d00019415164] xfs_reclaim_inodes_nr+0x54/0x70 [xfs] [c00f0160b0f0] [d000194297f8] xfs_fs_free_cached_objects+0x38/0x60 [xfs] [c00f0160b120] [c03172c8] super_cache_scan+0x1f8/0x210 [c00f0160b190] [c026301c] shrink_slab.part.13+0x21c/0x4c0 [c00f0160b2d0] [c0268088] shrink_zone+0x2d8/0x3c0 [c00f0160b380] [c026834c] do_try_to_free_pages+0x1dc/0x520 [c00f0160b450] [c026876c] try_to_free_pages+0xdc/0x250 [c00f0160b4e0] [c0251978] __alloc_pages_nodemask+0x868/0x10d0 [c00f0160b6f0] [c0567030] blk_mq_init_rq_map+0x160/0x380 [c00f0160b7a0] [c056758c] blk_mq_map_swqueue+0x33c/0x360 [c00f0160b820] [c0567904] blk_mq_queue_reinit+0x64/0xb0 [c00f0160b850] [c056a16c] blk_mq_queue_reinit_notify+0x19c/0x250 [c00f0160b8a0] [c00f5d38] notifier_call_chain+0x98/0x100 [c00f0160b8f0] [c00c5fb0] __cpu_notify+0x70/0xe0 [c00f0160b930] [c00c63c4] notify_prepare+0x44/0xb0 [c00f0160b9b0] [c00c52f4] cpuhp_invoke_callback+0x84/0x250 [c00f0160ba10] [c00c570c] cpuhp_up_callbacks+0x5c/0x120 [c00f0160ba60] [c00c7cb8] _cpu_up+0xf8/0x1d0 [c00f0160bac0] [c00c7eb0] do_cpu_up+0x120/0x150 [c00f0160bb40] [c06fe024] cpu_subsys_online+0x64/0xe0 [c00f0160bb90] [c06f5124] device_online+0xb4/0x120 [c00f0160bbd0] [c06f5244] online_store+0xb4/0xc0 [c00f0160bc20] [c06f0a68] dev_attr_store+0x68/0xa0 [c00f0160bc60] [c03ccc30] sysfs_kf_write+0x80/0xb0 [c00f0160bca0] [c03cbabc] kernfs_fop_write+0x17c/0x250 [c00f0160bcf0] [c030fe6c] __vfs_write+0x6c/0x1e0 [c00f0160bd90] [c0311490] vfs_write+0xd0/0x270 [c00f0160bde0] [c03131fc] SyS_write+0x6c/0x110 [c00f0160be30] [c0009204] system_call+0x38/0xec Signed-off-by: Gabriel Krisman Bertazi Cc: Brian King Cc: Douglas Miller Cc: linux-bl...@vger.kernel.org Cc: linux-scsi@vger.kernel.org --- block/blk-mq.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/block/blk-mq.c b/block/blk-mq.c index 6718f894fbe1..5f4e452eef72 100644 --- a/block/blk-mq.c +++ b/block/blk-mq.c @@ -1605,7 +1605,7 @@ static struct blk_mq_tags *blk_mq_init_rq_map(struct blk_mq_tag_set *set, INIT_LIST_HEAD(&tags->page_list); tags->rqs = kzalloc_node(set->queue_depth * sizeof(struct request *), -GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY, +GFP_NOIO | __GFP_NOWARN | __GFP_NORETRY, set->numa_node); if (!tags->rqs) { blk_mq_free_tags(tags); @@ -1631,7 +1631,7 @@ static struct blk_mq_tags *blk_mq_init_rq_map(struct blk_mq_tag_set *set, do { page = alloc_pages_node(set->numa_node, - GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY | __GFP_ZERO, + GFP_NOIO | __GFP_NOWARN | __GFP_NORETRY | __GFP_ZERO, this_order); if (page) break; @@ -1652,7 +1652,7 @@ static struct blk_mq_tags *blk_mq_init_rq_map(struct blk_mq_tag_set *set, * Allow kmemleak to scan these pages as they contain pointers * to additional allocations like via ops->init_request(). */ - kmemleak_alloc(p, order_to_size(this_order), 1, GFP_KERNEL); + kmemleak_alloc(p, order_to_size(this_order), 1, GFP_NOIO); entries_per_page = order_to_siz
Re: scsi: use-after-free in bio_copy_from_iter
On Tue, Dec 06, 2016 at 10:43:57AM +0100, Dmitry Vyukov wrote: > On Tue, Dec 6, 2016 at 10:32 AM, Johannes Thumshirn > wrote: > > On Mon, Dec 05, 2016 at 07:03:39PM +, Al Viro wrote: > >> On Mon, Dec 05, 2016 at 04:17:53PM +0100, Johannes Thumshirn wrote: > >> > 633 hp = &srp->header; > >> > [...] > >> > 646 hp->dxferp = (char __user *)buf + cmd_size; > >> > >> > So the memory for hp->dxferp comes from: > >> > 633 hp = &srp->header; > >> > >> > >> > >> > >From my debug instrumentation I see that the dxferp ends up in the > >> > iovec_iter's kvec->iov_base and the faulting address is always dxferp + > >> > n * > >> > 4k with n in [1, 16] (and we're copying 16 4k pages from the iovec into > >> > the > >> > bio). > >> > >> _Address_ of hp->dxferp comes from that assignment; the value is 'buf' > >> argument of sg_write() + small offset. In this case, it should point > >> inside a pipe buffer, which is, indeed, at a kernel address. Who'd > >> allocated srp is irrelevant. > > > > Yes I realized that as well when I had enough distance between me and the > > code... > > > >> > >> And if you end up dereferencing more than one page worth there, you do have > >> a problem - pipe buffers are not going to be that large. Could you slap > >> WARN_ON((size_t)input_size > count); > >> right after the calculation of input_size in sg_write() and see if it > >> triggers > >> on your reproducer? > > > > I did and it didn't trigger. What triggers is (as expected) a > > WARN_ON((size_t)mxsize > count); > > We have count at 80 and mxsize (which ends in hp->dxfer_len) at 65499. But > > the > > 65499 bytes are the len of the data we're suppost to be copying in via the > > iov. I'm still rather confused what's happening here, sorry. > > > I think the critical piece here is some kind of race or timing > condition. Note that the test program executes all of > memfd_create/write/open/sendfile twice. Second time the calls race > with each other, but they also can race with the first execution of > the calls. FWIW I've just run the reproducer once instead of looping it to check how it would normally behave and it bailes out at: 604 if (count < (SZ_SG_HEADER + 6)) 605 return -EIO;/* The minimum scsi command length is 6 bytes. */ That means, weren't going down the copy_form_iter() road at all. Usually, but sometimes we do. And then we try to copy 16 pages from the pipe buffer (is this correct?). The reproducer does: sendfile("/dev/sg0", memfd, offset_in_memfd, 0x1); I don't see how we get there? Could it be random data from the mmap() we point the memfd to? This bug is confusing to be honest. -- Johannes Thumshirn Storage jthumsh...@suse.de+49 911 74053 689 SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg GF: Felix Imendörffer, Jane Smithard, Graham Norton HRB 21284 (AG Nürnberg) Key fingerprint = EC38 9CAB C2C4 F25D 8600 D0D0 0393 969D 2D76 0850 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 00/10] virtio: sparse fixes
I run latest sparse from git on virtio drivers (turns out the version I had was rather outdated). This patchset fixes a couple of bugs this uncovered, and adds some annotations to make it sparse-clean. In particular, endian-ness is often tricky, so this patchset enabled endian-ness checks for sparse builds. Michael S. Tsirkin (10): virtio_console: drop unused config fields drm/virtio: fix endianness in primary_plane_update drm/virtio: fix lock context imbalance drm/virtio: annotate virtio_gpu_queue_ctrl_buffer_locked vhost: make interval tree static inline vhost: add missing __user annotations vsock/virtio: add a missing __le annotation vsock/virtio: mark an internal function static vsock/virtio: fix src/dst cid format virtio: enable endian checks for sparse builds drivers/char/virtio_console.c | 14 +++--- drivers/gpu/drm/virtio/virtgpu_plane.c | 4 ++-- drivers/gpu/drm/virtio/virtgpu_vq.c | 6 +- drivers/vhost/vhost.c | 12 ++-- net/vmw_vsock/virtio_transport.c| 2 +- net/vmw_vsock/virtio_transport_common.c | 16 drivers/block/Makefile | 1 + drivers/char/Makefile | 1 + drivers/char/hw_random/Makefile | 2 ++ drivers/gpu/drm/virtio/Makefile | 1 + drivers/net/Makefile| 3 +++ drivers/net/caif/Makefile | 1 + drivers/rpmsg/Makefile | 1 + drivers/s390/virtio/Makefile| 2 ++ drivers/scsi/Makefile | 1 + drivers/vhost/Makefile | 1 + drivers/virtio/Makefile | 3 +++ net/9p/Makefile | 1 + net/packet/Makefile | 1 + net/vmw_vsock/Makefile | 2 ++ 20 files changed, 50 insertions(+), 25 deletions(-) -- MST -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 10/10] virtio: enable endian checks for sparse builds
__CHECK_ENDIAN__ isn't on by default presumably because it triggers too many sparse warnings for correct code. But virtio is now clean of these warnings, and we want to keep it this way - enable this for sparse builds. Signed-off-by: Michael S. Tsirkin --- It seems that there should be a better way to do it, but this works too. drivers/block/Makefile | 1 + drivers/char/Makefile | 1 + drivers/char/hw_random/Makefile | 2 ++ drivers/gpu/drm/virtio/Makefile | 1 + drivers/net/Makefile| 3 +++ drivers/net/caif/Makefile | 1 + drivers/rpmsg/Makefile | 1 + drivers/s390/virtio/Makefile| 2 ++ drivers/scsi/Makefile | 1 + drivers/vhost/Makefile | 1 + drivers/virtio/Makefile | 3 +++ net/9p/Makefile | 1 + net/packet/Makefile | 1 + net/vmw_vsock/Makefile | 2 ++ 14 files changed, 21 insertions(+) diff --git a/drivers/block/Makefile b/drivers/block/Makefile index 1e9661e..597481c 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_BLK_DEV_OSD) += osdblk.o obj-$(CONFIG_BLK_DEV_UMEM) += umem.o obj-$(CONFIG_BLK_DEV_NBD) += nbd.o obj-$(CONFIG_BLK_DEV_CRYPTOLOOP) += cryptoloop.o +CFLAGS_virtio_blk.o += -D__CHECK_ENDIAN__ obj-$(CONFIG_VIRTIO_BLK) += virtio_blk.o obj-$(CONFIG_BLK_DEV_SX8) += sx8.o diff --git a/drivers/char/Makefile b/drivers/char/Makefile index 6e6c244..a99467d 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile @@ -6,6 +6,7 @@ obj-y += mem.o random.o obj-$(CONFIG_TTY_PRINTK) += ttyprintk.o obj-y += misc.o obj-$(CONFIG_ATARI_DSP56K) += dsp56k.o +CFLAGS_virtio_console.o += -D__CHECK_ENDIAN__ obj-$(CONFIG_VIRTIO_CONSOLE) += virtio_console.o obj-$(CONFIG_RAW_DRIVER) += raw.o obj-$(CONFIG_SGI_SNSC) += snsc.o snsc_event.o diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile index 5f52b1e..a2b0931 100644 --- a/drivers/char/hw_random/Makefile +++ b/drivers/char/hw_random/Makefile @@ -17,6 +17,8 @@ obj-$(CONFIG_HW_RANDOM_IXP4XX) += ixp4xx-rng.o obj-$(CONFIG_HW_RANDOM_OMAP) += omap-rng.o obj-$(CONFIG_HW_RANDOM_OMAP3_ROM) += omap3-rom-rng.o obj-$(CONFIG_HW_RANDOM_PASEMI) += pasemi-rng.o +CFLAGS_virtio_transport.o += -D__CHECK_ENDIAN__ +CFLAGS_virtio-rng.o += -D__CHECK_ENDIAN__ obj-$(CONFIG_HW_RANDOM_VIRTIO) += virtio-rng.o obj-$(CONFIG_HW_RANDOM_TX4939) += tx4939-rng.o obj-$(CONFIG_HW_RANDOM_MXC_RNGA) += mxc-rnga.o diff --git a/drivers/gpu/drm/virtio/Makefile b/drivers/gpu/drm/virtio/Makefile index 3fb8eac..1162366 100644 --- a/drivers/gpu/drm/virtio/Makefile +++ b/drivers/gpu/drm/virtio/Makefile @@ -3,6 +3,7 @@ # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. ccflags-y := -Iinclude/drm +ccflags-y += -D__CHECK_ENDIAN__ virtio-gpu-y := virtgpu_drv.o virtgpu_kms.o virtgpu_drm_bus.o virtgpu_gem.o \ virtgpu_fb.o virtgpu_display.o virtgpu_vq.o virtgpu_ttm.o \ diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 7336cbd..3f587de 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_EQUALIZER) += eql.o obj-$(CONFIG_IFB) += ifb.o obj-$(CONFIG_MACSEC) += macsec.o obj-$(CONFIG_MACVLAN) += macvlan.o +CFLAGS_macvtap.o += -D__CHECK_ENDIAN__ obj-$(CONFIG_MACVTAP) += macvtap.o obj-$(CONFIG_MII) += mii.o obj-$(CONFIG_MDIO) += mdio.o @@ -20,8 +21,10 @@ obj-$(CONFIG_NETCONSOLE) += netconsole.o obj-$(CONFIG_PHYLIB) += phy/ obj-$(CONFIG_RIONET) += rionet.o obj-$(CONFIG_NET_TEAM) += team/ +CFLAGS_tun.o += -D__CHECK_ENDIAN__ obj-$(CONFIG_TUN) += tun.o obj-$(CONFIG_VETH) += veth.o +CFLAGS_virtio_net.o += -D__CHECK_ENDIAN__ obj-$(CONFIG_VIRTIO_NET) += virtio_net.o obj-$(CONFIG_VXLAN) += vxlan.o obj-$(CONFIG_GENEVE) += geneve.o diff --git a/drivers/net/caif/Makefile b/drivers/net/caif/Makefile index 9bbd453..d1a922c 100644 --- a/drivers/net/caif/Makefile +++ b/drivers/net/caif/Makefile @@ -12,3 +12,4 @@ obj-$(CONFIG_CAIF_HSI) += caif_hsi.o # Virtio interface obj-$(CONFIG_CAIF_VIRTIO) += caif_virtio.o +CFLAGS_caif_virtio.o += -D__CHECK_ENDIAN__ diff --git a/drivers/rpmsg/Makefile b/drivers/rpmsg/Makefile index ae9c913..23c8b66 100644 --- a/drivers/rpmsg/Makefile +++ b/drivers/rpmsg/Makefile @@ -1,3 +1,4 @@ obj-$(CONFIG_RPMSG)+= rpmsg_core.o obj-$(CONFIG_RPMSG_QCOM_SMD) += qcom_smd.o obj-$(CONFIG_RPMSG_VIRTIO) += virtio_rpmsg_bus.o +CFLAGS_virtio_rpmsg_bus.o += -D__CHECK_ENDIAN__ diff --git a/drivers/s390/virtio/Makefile b/drivers/s390/virtio/Makefile index df40692..270ada5 100644 --- a/drivers/s390/virtio/Makefile +++ b/drivers/s390/virtio/Makefile @@ -6,6 +6,8 @@ # it under the terms of the GNU General Public License (version 2 only) # as published by the Free Software Foundation. +CFLAGS_virtio_ccw.o += -D__CHECK_ENDIAN__ +CFLAGS_kvm_virtio.o += -D__CHECK_ENDIAN__ s390-virtio-objs := virtio
Re: scsi: use-after-free in bio_copy_from_iter
On Tue, Dec 6, 2016 at 4:38 PM, Johannes Thumshirn wrote: > On Tue, Dec 06, 2016 at 10:43:57AM +0100, Dmitry Vyukov wrote: >> On Tue, Dec 6, 2016 at 10:32 AM, Johannes Thumshirn >> wrote: >> > On Mon, Dec 05, 2016 at 07:03:39PM +, Al Viro wrote: >> >> On Mon, Dec 05, 2016 at 04:17:53PM +0100, Johannes Thumshirn wrote: >> >> > 633 hp = &srp->header; >> >> > [...] >> >> > 646 hp->dxferp = (char __user *)buf + cmd_size; >> >> >> >> > So the memory for hp->dxferp comes from: >> >> > 633 hp = &srp->header; >> >> >> >> >> >> >> >> > >From my debug instrumentation I see that the dxferp ends up in the >> >> > iovec_iter's kvec->iov_base and the faulting address is always dxferp + >> >> > n * >> >> > 4k with n in [1, 16] (and we're copying 16 4k pages from the iovec into >> >> > the >> >> > bio). >> >> >> >> _Address_ of hp->dxferp comes from that assignment; the value is 'buf' >> >> argument of sg_write() + small offset. In this case, it should point >> >> inside a pipe buffer, which is, indeed, at a kernel address. Who'd >> >> allocated srp is irrelevant. >> > >> > Yes I realized that as well when I had enough distance between me and the >> > code... >> > >> >> >> >> And if you end up dereferencing more than one page worth there, you do >> >> have >> >> a problem - pipe buffers are not going to be that large. Could you slap >> >> WARN_ON((size_t)input_size > count); >> >> right after the calculation of input_size in sg_write() and see if it >> >> triggers >> >> on your reproducer? >> > >> > I did and it didn't trigger. What triggers is (as expected) a >> > WARN_ON((size_t)mxsize > count); >> > We have count at 80 and mxsize (which ends in hp->dxfer_len) at 65499. But >> > the >> > 65499 bytes are the len of the data we're suppost to be copying in via the >> > iov. I'm still rather confused what's happening here, sorry. >> >> >> I think the critical piece here is some kind of race or timing >> condition. Note that the test program executes all of >> memfd_create/write/open/sendfile twice. Second time the calls race >> with each other, but they also can race with the first execution of >> the calls. > > FWIW I've just run the reproducer once instead of looping it to check how it > would normally behave and it bailes out at: > > 604 if (count < (SZ_SG_HEADER + 6)) > 605 return -EIO;/* The minimum scsi command length is 6 > bytes. */ > > That means, weren't going down the copy_form_iter() road at all. Usually, but > sometimes we do. And then we try to copy 16 pages from the pipe buffer (is > this correct?). > The reproducer does: sendfile("/dev/sg0", memfd, offset_in_memfd, 0x1); > > I don't see how we get there? Could it be random data from the mmap() we point > the memfd to? > > This bug is confusing to be honest. Where does this count come from? What address in the user program? Is it 0x20012fxx? One possibility for non-deterministically changing inputs is that this part: case 2: NONFAILING(*(uint32_t*)0x20012fd8 = (uint32_t)0x28); NONFAILING(*(uint32_t*)0x20012fdc = (uint32_t)0x); NONFAILING(*(uint64_t*)0x20012fe0 = (uint64_t)0x0); NONFAILING(*(uint64_t*)0x20012fe8 = (uint64_t)0x993f); NONFAILING(*(uint64_t*)0x20012ff0 = (uint64_t)0xa8b); NONFAILING(*(uint32_t*)0x20012ff8 = (uint32_t)0xff); r[9] = syscall(__NR_write, r[2], 0x20012fd8ul, 0x28ul, 0, 0, 0, 0, 0, 0); runs concurrently with this part: case 0: r[0] = syscall(__NR_mmap, 0x2000ul, 0x13000ul, 0x3ul, 0x32ul, 0xul, 0x0ul, 0, 0, 0); So all of the input data to the write, or a subset of the input data, can be zeros. -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] scsi: avoid a permanent stop of the scsi device's request queue
On 12/06/16 01:12, Wei Fang wrote: > The scsi device is being setted to the SDEV_RUNNING state at the end of > the scan work. When the remote port reappears, scsi_target_unblock() > will be called, but the QUEUE_FLAG_STOPPED flag will not be cleared, > since scsi_internal_device_unblock() ignores SCSI devices in SDEV_RUNNING > state. It results in a permanent stop of the scsi device's request > queue. Every requests sended to it will be blocked. Hello Wei, scsi_device_set_state() does not allow the transition from SDEV_CREATED_BLOCK to SDEV_RUNNING. If a SCSI device is blocked after it has been added to the __devices list and before scsi_add_lun() finishes then I think the scan code will change its state into SDEV_BLOCK. Are you sure what you described above is what happened? Bart. -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH V3 01/11] megaraid_sas: Add new pci device Ids for SAS3.5 Generic Megaraid Controllers
On 5.12.2016 17:27, Sasikumar Chandrasekaran wrote: > This patch contains new pci device ids for SAS3.5 Generic Megaraid Controllers > > Signed-off-by: Sasikumar Chandrasekaran > --- > drivers/scsi/megaraid/megaraid_sas.h| 11 ++- > drivers/scsi/megaraid/megaraid_sas_base.c | 20 ++- > drivers/scsi/megaraid/megaraid_sas_fusion.c | 30 > ++--- > 3 files changed, 52 insertions(+), 9 deletions(-) > > diff --git a/drivers/scsi/megaraid/megaraid_sas.h > b/drivers/scsi/megaraid/megaraid_sas.h > index 0d2625b..f24ce88 100644 > --- a/drivers/scsi/megaraid/megaraid_sas.h > +++ b/drivers/scsi/megaraid/megaraid_sas.h > @@ -56,6 +56,14 @@ > #define PCI_DEVICE_ID_LSI_INTRUDER_240x00cf > #define PCI_DEVICE_ID_LSI_CUTLASS_52 0x0052 > #define PCI_DEVICE_ID_LSI_CUTLASS_53 0x0053 > +#define PCI_DEVICE_ID_LSI_MECTOR 0x00D4 > +#define PCI_DEVICE_ID_LSI_VENTURA0x0014 > +#define PCI_DEVICE_ID_LSI_CRUSADER 0x0015 Nack. This is not good, my test system panics instead of booting. megaraid_sas :02:0e.0: RDPQ mode: (disabled) BUG: unable to handle kernel paging request at 1e78 IP: [] megasas_issue_init_mfi+0x171/0x270 [megaraid_sas] you are already having a device with same device value in your pci_table (PCI_DEVICE_ID_DELL_PERC5 is also 0x15), so fix the switch in megasas_probe_one. Cheers, tomash (when sending new fixed versions, please add to the changed patches a text explaining what was changed in which version, like so - www.spinics.net/lists/linux-scsi/msg102122.html) > > @@ -5723,6 +5732,15 @@ static int megasas_probe_one(struct pci_dev *pdev, > instance->pdev = pdev; > > switch (instance->pdev->device) { > + case PCI_DEVICE_ID_LSI_VENTURA: > + case PCI_DEVICE_ID_LSI_MARLIN: > + case PCI_DEVICE_ID_LSI_MECTOR: > + case PCI_DEVICE_ID_LSI_CRUSADER: > + case PCI_DEVICE_ID_LSI_HARPOON: > + case PCI_DEVICE_ID_LSI_TOMCAT: > + case PCI_DEVICE_ID_LSI_VENTURA_4PORT: > + case PCI_DEVICE_ID_LSI_CRUSADER_4PORT: > + instance->is_ventura = true; > case PCI_DEVICE_ID_LSI_FUSION: > case PCI_DEVICE_ID_LSI_PLASMA: > case PCI_DEVICE_ID_LSI_INVADER: -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] net: return value of skb_linearize should be handled in Linux kernel
On Tue, Dec 06, 2016 at 03:10:33PM +0800, Zhouyi Zhou wrote: > kmalloc_reserve may fail to allocate memory inside skb_linearize, > which means skb_linearize's return value should not be ignored. > Following patch correct the uses of skb_linearize. > > Compiled in x86_64 FWIW compiled also on SPARC Reviewed-by: Yuval Shaia > > Signed-off-by: Zhouyi Zhou > --- > drivers/infiniband/hw/nes/nes_nic.c | 5 +++-- > drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c | 6 +- > drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 3 +-- > drivers/scsi/bnx2fc/bnx2fc_fcoe.c | 7 +-- > drivers/scsi/fcoe/fcoe.c | 5 - > net/tipc/link.c | 3 ++- > net/tipc/name_distr.c | 5 - > 7 files changed, 24 insertions(+), 10 deletions(-) > > diff --git a/drivers/infiniband/hw/nes/nes_nic.c > b/drivers/infiniband/hw/nes/nes_nic.c > index 2b27d13..69372ea 100644 > --- a/drivers/infiniband/hw/nes/nes_nic.c > +++ b/drivers/infiniband/hw/nes/nes_nic.c > @@ -662,10 +662,11 @@ static int nes_netdev_start_xmit(struct sk_buff *skb, > struct net_device *netdev) > nesnic->sq_head &= nesnic->sq_size-1; > } > } else { > - nesvnic->linearized_skbs++; > hoffset = skb_transport_header(skb) - skb->data; > nhoffset = skb_network_header(skb) - skb->data; > - skb_linearize(skb); > + if (skb_linearize(skb)) > + return NETDEV_TX_BUSY; > + nesvnic->linearized_skbs++; > skb_set_transport_header(skb, hoffset); > skb_set_network_header(skb, nhoffset); > if (!nes_nic_send(skb, netdev)) > diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c > b/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c > index 2a653ec..ab787cb 100644 > --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c > +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c > @@ -490,7 +490,11 @@ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter, >*/ > if ((fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA) && > (fctl & FC_FC_END_SEQ)) { > - skb_linearize(skb); > + int err = 0; > + > + err = skb_linearize(skb); > + if (err) > + return err; > crc = (struct fcoe_crc_eof *)skb_put(skb, sizeof(*crc)); > crc->fcoe_eof = FC_EOF_T; > } > diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c > b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c > index fee1f29..4926d48 100644 > --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c > +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c > @@ -2173,8 +2173,7 @@ static int ixgbe_clean_rx_irq(struct ixgbe_q_vector > *q_vector, > total_rx_bytes += ddp_bytes; > total_rx_packets += DIV_ROUND_UP(ddp_bytes, >mss); > - } > - if (!ddp_bytes) { > + } else { > dev_kfree_skb_any(skb); > continue; > } > diff --git a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c > b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c > index f9ddb61..197d02e 100644 > --- a/drivers/scsi/bnx2fc/bnx2fc_fcoe.c > +++ b/drivers/scsi/bnx2fc/bnx2fc_fcoe.c > @@ -542,8 +542,11 @@ static void bnx2fc_recv_frame(struct sk_buff *skb) > return; > } > > - if (skb_is_nonlinear(skb)) > - skb_linearize(skb); > + if (skb_linearize(skb)) { > + kfree_skb(skb); > + return; > + } > + > mac = eth_hdr(skb)->h_source; > dest_mac = eth_hdr(skb)->h_dest; > > diff --git a/drivers/scsi/fcoe/fcoe.c b/drivers/scsi/fcoe/fcoe.c > index 9bd41a3..f691b97 100644 > --- a/drivers/scsi/fcoe/fcoe.c > +++ b/drivers/scsi/fcoe/fcoe.c > @@ -1685,7 +1685,10 @@ static void fcoe_recv_frame(struct sk_buff *skb) > skb->dev ? skb->dev->name : ""); > > port = lport_priv(lport); > - skb_linearize(skb); /* check for skb_is_nonlinear is within > skb_linearize */ > + if (skb_linearize(skb)) { > + kfree_skb(skb); > + return; > + } > > /* >* Frame length checks and setting up the header pointers > diff --git a/net/tipc/link.c b/net/tipc/link.c > index bda89bf..077c570 100644 > --- a/net/tipc/link.c > +++ b/net/tipc/link.c > @@ -1446,7 +1446,8 @@ static int tipc_link_proto_rcv(struct tipc_link *l, > struct sk_buff *skb, > if (tipc_own_addr(l->net) > msg_prevnode(hdr)) > l->net_plane = msg_net_plane(hdr); > > - skb_linearize(skb); > + if (skb_linearize(skb)) > + goto exit; > hdr = buf_msg(skb); > d
[PATCH v4 0/6] qla2xxx: Feature udpates for driver.
Hi Martin, Please consider this revised series for inclusion into scsi-misc. This series has incorporated partial changes based on review comments from Christop and Hannes. There were few changes that are left out of this series as they will need regression testing and we have patches for target infrastucture already based on these patch series which I am going to send out soon. We will submit additional patches with the changes suggested as soon as we have completed regression with them. Here's list of changes that will be posted as seperate series after they have gone through regression cycle. o Converting uint32_t to bitops and macros to inline function. o Use waitqueue instead of busy wait. o Use of srb pool from the scsi_command instead of allocating/deallocatig mempool in the driver. Changes from v3 -> v4 o Removed now stale rsp_q refrence from qla_msix_entry. o Merged the multiple files into exsisting code o Enabled Mutiqueue by default. o Updated to use kcalloc instead of kzalloc Changes from v2 --> v3 o Added patch to utilize pci_{alloc|free}_irq_vectors call as per Christoph's suggestion. o Clean up IRQ affinity and drop num_online_cpu() usage in driver as per review comments from Hannes & Christoph. o Added patch description for mailbox starvation patch. Also added Reviewed-by signature from Hannes. Changes from v1 --> v2 o Split up the patches for Multiqueue into infrastucture changes and support for adding multiqueue capablity in the driver as per Ewan's suggestion. o Incorporate new pci_irq_alloc_vector call as per Christoph's suggestion. o To address comments related to Mailbox patches by Ewan, I have reworked the patch to clean-up mailbox workqueue. Himanshu Madhani (1): qla2xxx: Only allow operational MBX to proceed during RESET. Michael Hernandez (3): qla2xxx: Utilize pci_alloc_irq_vectors/pci_free_irq_vectors calls. qla2xxx: Add multiple queue pair functionality. qla2xxx: Add Block Multi Queue functionality. Quinn Tran (1): qla2xxx: Fix Target mode handling with Multiqueue changes. Samy (1): qla2xxx: Fix mailbox command timeout due to starvation drivers/scsi/qla2xxx/qla_attr.c | 36 ++- drivers/scsi/qla2xxx/qla_dbg.c| 4 +- drivers/scsi/qla2xxx/qla_def.h| 111 +++-- drivers/scsi/qla2xxx/qla_gbl.h| 28 ++- drivers/scsi/qla2xxx/qla_init.c | 173 +- drivers/scsi/qla2xxx/qla_inline.h | 30 +++ drivers/scsi/qla2xxx/qla_iocb.c | 407 +++ drivers/scsi/qla2xxx/qla_isr.c| 223 + drivers/scsi/qla2xxx/qla_mbx.c| 165 ++--- drivers/scsi/qla2xxx/qla_mid.c| 116 - drivers/scsi/qla2xxx/qla_os.c | 487 -- 11 files changed, 1353 insertions(+), 427 deletions(-) -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 1/6] qla2xxx: Only allow operational MBX to proceed during RESET.
This patch is allowing only ROM mailbox command which are necessary to initialize chip after a reset has been issued. In a target environment, there could be a user space daemon which can issue statistics and other management mailbox command which are non-critical. This patch will timeout non critical mailbox commands immediately rather than waiting for timeout, if driver detects that chip reset has been issued or chip reset is in progress. Reviewed-by: Hannes Reinecke Reviewed-by: Christoph Hellwig Signed-off-by: Himanshu Madhani Signed-off-by: Giridhar Malavali --- drivers/scsi/qla2xxx/qla_mbx.c | 52 ++ 1 file changed, 52 insertions(+) diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index 23698c9..b31c36b 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -10,6 +10,43 @@ #include #include +struct rom_cmd { + uint16_t cmd; +} rom_cmds[] = { + { MBC_LOAD_RAM }, + { MBC_EXECUTE_FIRMWARE }, + { MBC_READ_RAM_WORD }, + { MBC_MAILBOX_REGISTER_TEST }, + { MBC_VERIFY_CHECKSUM }, + { MBC_GET_FIRMWARE_VERSION }, + { MBC_LOAD_RISC_RAM }, + { MBC_DUMP_RISC_RAM }, + { MBC_LOAD_RISC_RAM_EXTENDED }, + { MBC_DUMP_RISC_RAM_EXTENDED }, + { MBC_WRITE_RAM_WORD_EXTENDED }, + { MBC_READ_RAM_EXTENDED }, + { MBC_GET_RESOURCE_COUNTS }, + { MBC_SET_FIRMWARE_OPTION }, + { MBC_MID_INITIALIZE_FIRMWARE }, + { MBC_GET_FIRMWARE_STATE }, + { MBC_GET_MEM_OFFLOAD_CNTRL_STAT }, + { MBC_GET_RETRY_COUNT }, + { MBC_TRACE_CONTROL }, +}; + +static int is_rom_cmd(uint16_t cmd) +{ + int i; + struct rom_cmd *wc; + + for (i = 0; i < ARRAY_SIZE(rom_cmds); i++) { + wc = rom_cmds + i; + if (wc->cmd == cmd) + return 1; + } + + return 0; +} /* * qla2x00_mailbox_command @@ -92,6 +129,17 @@ return QLA_FUNCTION_TIMEOUT; } + /* check if ISP abort is active and return cmd with timeout */ + if ((test_bit(ABORT_ISP_ACTIVE, &base_vha->dpc_flags) || + test_bit(ISP_ABORT_RETRY, &base_vha->dpc_flags) || + test_bit(ISP_ABORT_NEEDED, &base_vha->dpc_flags)) && + !is_rom_cmd(mcp->mb[0])) { + ql_log(ql_log_info, vha, 0x1005, + "Cmd 0x%x aborted with timeout since ISP Abort is pending\n", + mcp->mb[0]); + return QLA_FUNCTION_TIMEOUT; + } + /* * Wait for active mailbox commands to finish by waiting at most tov * seconds. This is to serialize actual issuing of mailbox cmds during @@ -178,6 +226,7 @@ WRT_REG_WORD(®->isp.hccr, HCCR_SET_HOST_INT); spin_unlock_irqrestore(&ha->hardware_lock, flags); + wait_time = jiffies; if (!wait_for_completion_timeout(&ha->mbx_intr_comp, mcp->tov * HZ)) { ql_dbg(ql_dbg_mbx, vha, 0x117a, @@ -186,6 +235,9 @@ clear_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags); spin_unlock_irqrestore(&ha->hardware_lock, flags); } + if (time_after(jiffies, wait_time + 5 * HZ)) + ql_log(ql_log_warn, vha, 0x1015, "cmd=0x%x, waited %d msecs\n", + command, jiffies_to_msecs(jiffies - wait_time)); } else { ql_dbg(ql_dbg_mbx, vha, 0x1011, "Cmd=%x Polling Mode.\n", command); -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 2/6] qla2xxx: Fix mailbox command timeout due to starvation
From: Samy This patch helps resolve some of the mailbox timeout issue discovered during large SAN emulation testing where 1000+ initiators are trying to log into target mode personality. Since current mailbox interface handles submission and processing of commands in a sequential order, command could timeout resulting in some initiator not being able to log into target. Reviewed-by: Hannes Reinecke Signed-off-by: Samy Signed-off-by: Himanshu Madhani --- drivers/scsi/qla2xxx/qla_def.h | 3 ++ drivers/scsi/qla2xxx/qla_mbx.c | 88 ++ drivers/scsi/qla2xxx/qla_os.c | 24 3 files changed, 91 insertions(+), 24 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 5236e3f..9a6ddcb 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -3553,6 +3553,9 @@ struct qla_hw_data { uint32_tidc_audit_ts; uint32_tidc_extend_tmo; + /* mail box work queue */ + struct workqueue_struct *mbx_wq; + /* DPC low-priority workqueue */ struct workqueue_struct *dpc_lp_wq; struct work_struct idc_aen; diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index b31c36b..14068fb 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -10,6 +10,14 @@ #include #include +struct mbx_cmd_info_t { + mbx_cmd_t *mcp; + scsi_qla_host_t *vha; + struct work_struct work; + struct completion comp; + int status; +}; + struct rom_cmd { uint16_t cmd; } rom_cmds[] = { @@ -68,7 +76,7 @@ static int is_rom_cmd(uint16_t cmd) * Kernel context. */ static int -qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) +__qla2x00_mailbox_command(scsi_qla_host_t *vha, mbx_cmd_t *mcp) { int rval, i; unsigned longflags = 0; @@ -140,19 +148,6 @@ static int is_rom_cmd(uint16_t cmd) return QLA_FUNCTION_TIMEOUT; } - /* -* Wait for active mailbox commands to finish by waiting at most tov -* seconds. This is to serialize actual issuing of mailbox cmds during -* non ISP abort time. -*/ - if (!wait_for_completion_timeout(&ha->mbx_cmd_comp, mcp->tov * HZ)) { - /* Timeout occurred. Return error. */ - ql_log(ql_log_warn, vha, 0x1005, - "Cmd access timeout, cmd=0x%x, Exiting.\n", - mcp->mb[0]); - return QLA_FUNCTION_TIMEOUT; - } - ha->flags.mbox_busy = 1; /* Save mailbox command for debug */ ha->mcp = mcp; @@ -217,7 +212,7 @@ static int is_rom_cmd(uint16_t cmd) ql_dbg(ql_dbg_mbx, vha, 0x1010, "Pending mailbox timeout, exiting.\n"); rval = QLA_FUNCTION_TIMEOUT; - goto premature_exit; + goto mbx_done; } WRT_REG_DWORD(®->isp82.hint, HINT_MBX_INT_PENDING); } else if (IS_FWI2_CAPABLE(ha)) @@ -251,7 +246,7 @@ static int is_rom_cmd(uint16_t cmd) ql_dbg(ql_dbg_mbx, vha, 0x1012, "Pending mailbox timeout, exiting.\n"); rval = QLA_FUNCTION_TIMEOUT; - goto premature_exit; + goto mbx_done; } WRT_REG_DWORD(®->isp82.hint, HINT_MBX_INT_PENDING); } else if (IS_FWI2_CAPABLE(ha)) @@ -297,7 +292,7 @@ static int is_rom_cmd(uint16_t cmd) rval = QLA_FUNCTION_FAILED; ql_log(ql_log_warn, vha, 0x1015, "FW hung = %d.\n", ha->flags.isp82xx_fw_hung); - goto premature_exit; + goto mbx_done; } if (ha->mailbox_out[0] != MBS_COMMAND_COMPLETE) @@ -353,7 +348,7 @@ static int is_rom_cmd(uint16_t cmd) set_bit(PCI_ERR, &base_vha->dpc_flags); ha->flags.mbox_busy = 0; rval = QLA_FUNCTION_TIMEOUT; - goto premature_exit; + goto mbx_done; } /* Attempt to capture firmware dump for further @@ -431,8 +426,6 @@ static int is_rom_cmd(uint16_t cmd) command, mcp->mb[0]); set_bit(ABORT_ISP_ACTIVE, &vha->dpc_flags); clear_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); - /* Allow next mbx cmd to come in. */ - compl
[PATCH v4 5/6] qla2xxx: Add Block Multi Queue functionality.
From: Michael Hernandez Tell the SCSI layer how many hardware queues we have based on the number of max queue pairs created. The number of max queue pairs created will depend on number of MSI-X vector count. This feature can be turned on via CONFIG_SCSI_MQ_DEFAULT or passing scsi_mod.use_blk_mq=Y as a parameter to the kernel Reviewed-by: Hannes Reinecke Signed-off-by: Sawan Chandak Signed-off-by: Michael Hernandez Signed-off-by: Himanshu Madhani --- drivers/scsi/qla2xxx/qla_os.c | 37 - 1 file changed, 32 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index c5d0525..bc7008d 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -738,16 +738,26 @@ static void qla2x00_free_queues(struct qla_hw_data *ha) struct scsi_qla_host *base_vha = pci_get_drvdata(ha->pdev); srb_t *sp; int rval; - struct qla_qpair *qpair; + struct qla_qpair *qpair = NULL; + uint32_t tag; + uint16_t hwq; if (unlikely(test_bit(UNLOADING, &base_vha->dpc_flags))) { cmd->result = DID_NO_CONNECT << 16; goto qc24_fail_command; } - if (vha->vp_idx && vha->qpair) { - qpair = vha->qpair; - return qla2xxx_mqueuecommand(host, cmd, qpair); + if (ha->mqenable) { + if (shost_use_blk_mq(vha->host)) { + tag = blk_mq_unique_tag(cmd->request); + hwq = blk_mq_unique_tag_to_hwq(tag); + qpair = ha->queue_pair_map[hwq]; + } else if (vha->vp_idx && vha->qpair) { + qpair = vha->qpair; + } + + if (qpair) + return qla2xxx_mqueuecommand(host, cmd, qpair); } if (ha->flags.eeh_busy) { @@ -2520,6 +2530,7 @@ static void qla2x00_destroy_mbx_wq(struct qla_hw_data *ha) uint16_t req_length = 0, rsp_length = 0; struct req_que *req = NULL; struct rsp_que *rsp = NULL; + int i; bars = pci_select_bars(pdev, IORESOURCE_MEM | IORESOURCE_IO); sht = &qla2xxx_driver_template; @@ -2885,6 +2896,16 @@ static void qla2x00_destroy_mbx_wq(struct qla_hw_data *ha) goto probe_init_failed; } + if (ha->mqenable && shost_use_blk_mq(host)) { + /* number of hardware queues supported by blk/scsi-mq*/ + host->nr_hw_queues = ha->max_qpairs; + + ql_dbg(ql_dbg_init, base_vha, 0x0192, + "blk/scsi-mq enabled, HW queues = %d.\n", host->nr_hw_queues); + } else + ql_dbg(ql_dbg_init, base_vha, 0x0193, + "blk/scsi-mq disabled.\n"); + qlt_probe_one_stage1(base_vha, ha); pci_save_state(pdev); @@ -2985,8 +3006,14 @@ static void qla2x00_destroy_mbx_wq(struct qla_hw_data *ha) host->can_queue, base_vha->req, base_vha->mgmt_svr_loop_id, host->sg_tablesize); - if (ha->mqenable) + if (ha->mqenable) { ha->wq = alloc_workqueue("qla2xxx_wq", WQ_MEM_RECLAIM, 1); + /* Create start of day qpairs for Block MQ */ + if (shost_use_blk_mq(host)) { + for (i = 0; i < ha->max_qpairs; i++) + qla2xxx_create_qpair(base_vha, 5, 0); + } + } if (ha->flags.running_gold_fw) goto skip_dpc; -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 6/6] qla2xxx: Fix Target mode handling with Multiqueue changes.
From: Quinn Tran - Fix race condition between dpc_thread accessing Multiqueue resources and qla2x00_remove_one thread trying to free resource. - Fix out of order free for Multiqueue resources. Also, Multiqueue interrupts needs a workqueue. Interrupt needed to stop before the wq can be destroyed. Reviewed-by: Hannes Reinecke Signed-off-by: Quinn Tran Signed-off-by: Himanshu Madhani --- drivers/scsi/qla2xxx/qla_def.h | 3 ++- drivers/scsi/qla2xxx/qla_init.c | 2 +- drivers/scsi/qla2xxx/qla_isr.c | 20 +++- drivers/scsi/qla2xxx/qla_os.c | 51 ++--- 4 files changed, 49 insertions(+), 27 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 7629ef9..84f2cc3 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -2734,7 +2734,8 @@ struct isp_operations { #define QLA_MSIX_DEFAULT 0x00 #define QLA_MSIX_RSP_Q 0x01 -#define QLA_MSIX_QPAIR_MULTIQ_RSP_Q0x02 +#define QLA_ATIO_VECTOR0x02 +#define QLA_MSIX_QPAIR_MULTIQ_RSP_Q0x03 #define QLA_MIDX_DEFAULT 0 #define QLA_MIDX_RSP_Q 1 diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 400ffd1..632d5f3 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -6764,7 +6764,7 @@ struct qla_qpair *qla2xxx_create_qpair(struct scsi_qla_host *vha, int qos, int v qpair->vp_idx = vp_idx; for (i = 0; i < ha->msix_count; i++) { - msix = &ha->msix_entries[i + 2]; + msix = &ha->msix_entries[i]; if (msix->in_use) continue; qpair->msix = msix; diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 58b4be7..98e4904 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -3005,6 +3005,7 @@ struct qla_init_msix_entry { static struct qla_init_msix_entry msix_entries[] = { { "qla2xxx (default)", qla24xx_msix_default }, { "qla2xxx (rsp_q)", qla24xx_msix_rsp_q }, + { "qla2xxx (atio_q)", qla83xx_msix_atio_q }, { "qla2xxx (qpair_multiq)", qla2xxx_msix_rsp_q }, }; @@ -3013,17 +3014,10 @@ struct qla_init_msix_entry { { "qla2xxx (rsp_q)", qla82xx_msix_rsp_q }, }; -static struct qla_init_msix_entry qla83xx_msix_entries[] = { - { "qla2xxx (default)", qla24xx_msix_default }, - { "qla2xxx (rsp_q)", qla24xx_msix_rsp_q }, - { "qla2xxx (atio_q)", qla83xx_msix_atio_q }, -}; - static int qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp) { #define MIN_MSIX_COUNT 2 -#define ATIO_VECTOR2 int i, ret; struct qla_msix_entry *qentry; scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); @@ -3080,7 +3074,7 @@ struct qla_init_msix_entry { } /* Enable MSI-X vectors for the base queue */ - for (i = 0; i < 2; i++) { + for (i = 0; i < (QLA_MSIX_RSP_Q + 1); i++) { qentry = &ha->msix_entries[i]; qentry->handle = rsp; rsp->msix = qentry; @@ -3097,6 +3091,7 @@ struct qla_init_msix_entry { if (ret) goto msix_register_fail; qentry->have_irq = 1; + qentry->in_use = 1; /* Register for CPU affinity notification. */ irq_set_affinity_notifier(qentry->vector, &qentry->irq_notify); @@ -3116,14 +3111,15 @@ struct qla_init_msix_entry { * queue. */ if (QLA_TGT_MODE_ENABLED() && IS_ATIO_MSIX_CAPABLE(ha)) { - qentry = &ha->msix_entries[ATIO_VECTOR]; + qentry = &ha->msix_entries[QLA_ATIO_VECTOR]; rsp->msix = qentry; qentry->handle = rsp; scnprintf(qentry->name, sizeof(qentry->name), - qla83xx_msix_entries[ATIO_VECTOR].name); + msix_entries[QLA_ATIO_VECTOR].name); + qentry->in_use = 1; ret = request_irq(qentry->vector, - qla83xx_msix_entries[ATIO_VECTOR].handler, - 0, qla83xx_msix_entries[ATIO_VECTOR].name, rsp); + msix_entries[QLA_ATIO_VECTOR].handler, + 0, msix_entries[QLA_ATIO_VECTOR].name, rsp); qentry->have_irq = 1; } diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index bc7008d..544f957 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -436,24 +436,41 @@ static void qla2x00_free_queues(struct qla_hw_data *ha) struct req_que *req; struct rsp_que *rsp; int cnt; + unsigned long flags; + spin_lock_irqsave(&ha->hardware_lock, flags); for (cnt = 0; cnt < ha->max_req_queues; cnt++) {
[PATCH v4 3/6] qla2xxx: Utilize pci_alloc_irq_vectors/pci_free_irq_vectors calls.
From: Michael Hernandez Replaces the old pci_enable_msi[x]* and pci_disable_msi[x] calls. Signed-off-by: Michael Hernandez Signed-off-by: Himanshu Madhani --- drivers/scsi/qla2xxx/qla_def.h | 2 +- drivers/scsi/qla2xxx/qla_isr.c | 89 -- drivers/scsi/qla2xxx/qla_mid.c | 2 +- 3 files changed, 36 insertions(+), 57 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 9a6ddcb..8a6780c 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -2747,7 +2747,7 @@ struct qla_msix_entry { int have_irq; uint32_t vector; uint16_t entry; - struct rsp_que *rsp; + void *handle; struct irq_affinity_notify irq_notify; int cpuid; }; diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 19f1848..0601ba2 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -3025,52 +3025,17 @@ struct qla_init_msix_entry { { "qla2xxx (atio_q)", qla83xx_msix_atio_q }, }; -static void -qla24xx_disable_msix(struct qla_hw_data *ha) -{ - int i; - struct qla_msix_entry *qentry; - scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); - - for (i = 0; i < ha->msix_count; i++) { - qentry = &ha->msix_entries[i]; - if (qentry->have_irq) { - /* un-register irq cpu affinity notification */ - irq_set_affinity_notifier(qentry->vector, NULL); - free_irq(qentry->vector, qentry->rsp); - } - } - pci_disable_msix(ha->pdev); - kfree(ha->msix_entries); - ha->msix_entries = NULL; - ha->flags.msix_enabled = 0; - ql_dbg(ql_dbg_init, vha, 0x0042, - "Disabled the MSI.\n"); -} - static int qla24xx_enable_msix(struct qla_hw_data *ha, struct rsp_que *rsp) { #define MIN_MSIX_COUNT 2 #define ATIO_VECTOR2 int i, ret; - struct msix_entry *entries; struct qla_msix_entry *qentry; scsi_qla_host_t *vha = pci_get_drvdata(ha->pdev); - entries = kzalloc(sizeof(struct msix_entry) * ha->msix_count, - GFP_KERNEL); - if (!entries) { - ql_log(ql_log_warn, vha, 0x00bc, - "Failed to allocate memory for msix_entry.\n"); - return -ENOMEM; - } - - for (i = 0; i < ha->msix_count; i++) - entries[i].entry = i; - - ret = pci_enable_msix_range(ha->pdev, - entries, MIN_MSIX_COUNT, ha->msix_count); + ret = pci_alloc_irq_vectors(ha->pdev, + MIN_MSIX_COUNT, ha->msix_count, PCI_IRQ_MSIX|PCI_IRQ_AFFINITY); if (ret < 0) { ql_log(ql_log_fatal, vha, 0x00c7, "MSI-X: Failed to enable support, " @@ -3097,10 +3062,10 @@ struct qla_init_msix_entry { for (i = 0; i < ha->msix_count; i++) { qentry = &ha->msix_entries[i]; - qentry->vector = entries[i].vector; - qentry->entry = entries[i].entry; + qentry->vector = pci_irq_vector(ha->pdev, i); + qentry->entry = i; qentry->have_irq = 0; - qentry->rsp = NULL; + qentry->handle = NULL; qentry->irq_notify.notify = qla_irq_affinity_notify; qentry->irq_notify.release = qla_irq_affinity_release; qentry->cpuid = -1; @@ -3109,7 +3074,7 @@ struct qla_init_msix_entry { /* Enable MSI-X vectors for the base queue */ for (i = 0; i < 2; i++) { qentry = &ha->msix_entries[i]; - qentry->rsp = rsp; + qentry->handle = rsp; rsp->msix = qentry; if (IS_P3P_TYPE(ha)) ret = request_irq(qentry->vector, @@ -3142,7 +3107,7 @@ struct qla_init_msix_entry { */ if (QLA_TGT_MODE_ENABLED() && IS_ATIO_MSIX_CAPABLE(ha)) { qentry = &ha->msix_entries[ATIO_VECTOR]; - qentry->rsp = rsp; + qentry->handle = rsp; rsp->msix = qentry; ret = request_irq(qentry->vector, qla83xx_msix_entries[ATIO_VECTOR].handler, @@ -3155,7 +3120,7 @@ struct qla_init_msix_entry { ql_log(ql_log_fatal, vha, 0x00cb, "MSI-X: unable to register handler -- %x/%d.\n", qentry->vector, ret); - qla24xx_disable_msix(ha); + qla2x00_free_irqs(vha); ha->mqenable = 0; goto msix_out; } @@ -3177,7 +3142,6 @@ struct qla_init_msix_entry { ha->mqiobase, ha->max_rsp_queues, ha->max_req_queues); msix_out: - kfree(entries); return ret; } @@ -3230,7 +3194,7 @@ struct qla_init_msix_entry { !IS_QLA27XX(ha)) goto skip_msi; -
[PATCH v4 4/6] qla2xxx: Add multiple queue pair functionality.
From: Michael Hernandez Replaced existing multiple queue functionality with framework that allows for the creation of pairs of request and response queues, either at start of day or dynamically. Queue pair creation depend on module parameter "ql2xmqsupport", which need to be enabled to create queue pair. Signed-off-by: Sawan Chandak Signed-off-by: Michael Hernandez Signed-off-by: Himanshu Madhani --- drivers/scsi/qla2xxx/qla_attr.c | 36 ++-- drivers/scsi/qla2xxx/qla_dbg.c| 4 +- drivers/scsi/qla2xxx/qla_def.h| 105 -- drivers/scsi/qla2xxx/qla_gbl.h| 28 ++- drivers/scsi/qla2xxx/qla_init.c | 173 +++- drivers/scsi/qla2xxx/qla_inline.h | 30 +++ drivers/scsi/qla2xxx/qla_iocb.c | 407 ++ drivers/scsi/qla2xxx/qla_isr.c| 122 +++- drivers/scsi/qla2xxx/qla_mbx.c| 33 ++-- drivers/scsi/qla2xxx/qla_mid.c| 114 ++- drivers/scsi/qla2xxx/qla_os.c | 395 11 files changed, 1113 insertions(+), 334 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index fe7469c..47eb4d5 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -1988,9 +1988,9 @@ struct device_attribute *qla2x00_host_attrs[] = { scsi_qla_host_t *base_vha = shost_priv(fc_vport->shost); scsi_qla_host_t *vha = NULL; struct qla_hw_data *ha = base_vha->hw; - uint16_t options = 0; int cnt; struct req_que *req = ha->req_q_map[0]; + struct qla_qpair *qpair; ret = qla24xx_vport_create_req_sanity_check(fc_vport); if (ret) { @@ -2075,15 +2075,9 @@ struct device_attribute *qla2x00_host_attrs[] = { qlt_vport_create(vha, ha); qla24xx_vport_disable(fc_vport, disable); - if (ha->flags.cpu_affinity_enabled) { - req = ha->req_q_map[1]; - ql_dbg(ql_dbg_multiq, vha, 0xc000, - "Request queue %p attached with " - "VP[%d], cpu affinity =%d\n", - req, vha->vp_idx, ha->flags.cpu_affinity_enabled); - goto vport_queue; - } else if (ql2xmaxqueues == 1 || !ha->npiv_info) + if (!ql2xmqsupport || !ha->npiv_info) goto vport_queue; + /* Create a request queue in QoS mode for the vport */ for (cnt = 0; cnt < ha->nvram_npiv_size; cnt++) { if (memcmp(ha->npiv_info[cnt].port_name, vha->port_name, 8) == 0 @@ -2095,20 +2089,20 @@ struct device_attribute *qla2x00_host_attrs[] = { } if (qos) { - ret = qla25xx_create_req_que(ha, options, vha->vp_idx, 0, 0, - qos); - if (!ret) + qpair = qla2xxx_create_qpair(vha, qos, vha->vp_idx); + if (!qpair) ql_log(ql_log_warn, vha, 0x7084, - "Can't create request queue for VP[%d]\n", + "Can't create qpair for VP[%d]\n", vha->vp_idx); else { ql_dbg(ql_dbg_multiq, vha, 0xc001, - "Request Que:%d Q0s: %d) created for VP[%d]\n", - ret, qos, vha->vp_idx); + "Queue pair: %d Qos: %d) created for VP[%d]\n", + qpair->id, qos, vha->vp_idx); ql_dbg(ql_dbg_user, vha, 0x7085, - "Request Que:%d Q0s: %d) created for VP[%d]\n", - ret, qos, vha->vp_idx); - req = ha->req_q_map[ret]; + "Queue Pair: %d Qos: %d) created for VP[%d]\n", + qpair->id, qos, vha->vp_idx); + req = qpair->req; + vha->qpair = qpair; } } @@ -2162,10 +2156,10 @@ struct device_attribute *qla2x00_host_attrs[] = { clear_bit(vha->vp_idx, ha->vp_idx_map); mutex_unlock(&ha->vport_lock); - if (vha->req->id && !ha->flags.cpu_affinity_enabled) { - if (qla25xx_delete_req_que(vha, vha->req) != QLA_SUCCESS) + if (vha->qpair->vp_idx == vha->vp_idx) { + if (qla2xxx_delete_qpair(vha, vha->qpair) != QLA_SUCCESS) ql_log(ql_log_warn, vha, 0x7087, - "Queue delete failed.\n"); + "Queue Pair delete failed.\n"); } ql_log(ql_log_info, vha, 0x7088, "VP[%d] deleted.\n", id); diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index 45af34d..21d9fb7 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c @@ -11,7 +11,7 @@ * -- * | Level| Last Value Used | Holes | * --
[PATCH] scsi: qla4xxx: Use dma_pool_zalloc
We should use dma_pool_zalloc instead of dma_pool_alloc/memset Signed-off-by: Souptick joarder --- drivers/scsi/qla4xxx/ql4_mbx.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/scsi/qla4xxx/ql4_mbx.c b/drivers/scsi/qla4xxx/ql4_mbx.c index c291fdf..f2edfd7 100644 --- a/drivers/scsi/qla4xxx/ql4_mbx.c +++ b/drivers/scsi/qla4xxx/ql4_mbx.c @@ -1587,12 +1587,11 @@ int qla4xxx_get_chap(struct scsi_qla_host *ha, char *username, char *password, struct ql4_chap_table *chap_table; dma_addr_t chap_dma; - chap_table = dma_pool_alloc(ha->chap_dma_pool, GFP_KERNEL, &chap_dma); + chap_table = dma_pool_zalloc(ha->chap_dma_pool, GFP_KERNEL, &chap_dma); if (chap_table == NULL) return -ENOMEM; chap_size = sizeof(struct ql4_chap_table); - memset(chap_table, 0, chap_size); if (is_qla40XX(ha)) offset = FLASH_CHAP_OFFSET | (idx * chap_size); -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 02/22] qla2xxx: Include ATIO queue in firmware dump when in target mode
Signed-off-by: Himanshu Madhani Signed-off-by: Giridhar Malavali --- drivers/scsi/qla2xxx/qla_tmpl.c | 24 1 file changed, 24 insertions(+) diff --git a/drivers/scsi/qla2xxx/qla_tmpl.c b/drivers/scsi/qla2xxx/qla_tmpl.c index 36935c9..9ae89af 100644 --- a/drivers/scsi/qla2xxx/qla_tmpl.c +++ b/drivers/scsi/qla2xxx/qla_tmpl.c @@ -433,6 +433,18 @@ static inline void (*qla27xx_read_vector(uint width))(void __iomem*, void *, ulo count++; } } + } else if (QLA_TGT_MODE_ENABLED() && + (ent->t263.queue_type == T263_QUEUE_TYPE_ATIO)) { + struct qla_hw_data *ha = vha->hw; + struct atio *atr = ha->tgt.atio_ring; + + if (atr || !buf) { + length = ha->tgt.atio_q_length; + qla27xx_insert16(0, buf, len); + qla27xx_insert16(length, buf, len); + qla27xx_insertbuf(atr, length * sizeof(*atr), buf, len); + count++; + } } else { ql_dbg(ql_dbg_misc, vha, 0xd026, "%s: unknown queue %x\n", __func__, ent->t263.queue_type); @@ -676,6 +688,18 @@ static inline void (*qla27xx_read_vector(uint width))(void __iomem*, void *, ulo count++; } } + } else if (QLA_TGT_MODE_ENABLED() && + (ent->t274.queue_type == T274_QUEUE_TYPE_ATIO_SHAD)) { + struct qla_hw_data *ha = vha->hw; + struct atio *atr = ha->tgt.atio_ring_ptr; + + if (atr || !buf) { + qla27xx_insert16(0, buf, len); + qla27xx_insert16(1, buf, len); + qla27xx_insert32(ha->tgt.atio_q_in ? *ha->tgt.atio_q_in : 0, + buf, len); + count++; + } } else { ql_dbg(ql_dbg_misc, vha, 0xd02f, "%s: unknown queue %x\n", __func__, ent->t274.queue_type); -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 00/22] qla2xxx: Target code enhancemets and feature update
Hi Nic, Please consider this series for target-pending. This series is based on scsi-misc series that was submitted earlier today. Here's link for that series http://marc.info/?l=linux-scsi&m=148105128210090&w=2 This series contains following changes o Clean up Target code and tcm_qla2xxx for cleaner interaction. o Enhanced and strengthen support for T10-DIF/PI. o Renamed qlini_mode to qlop_mode for better readbility. o Improve driver capability to manage dual personality (i.e. Initiator and Target) simultaneously. o Added capability to send non-critical MBX via IOCB path. o Some of the pending bug-fixes for target code. Thanks, Himanshu Himanshu Madhani (3): qla2xxx: Include ATIO queue in firmware dump when in target mode qla2xxx: Set tcm_qla2xxx version to automatically track qla2xxx version. qla2xxx: Clear BIT 15 in NVRAM during initialization. Joe Carnuccio (1): qla2xxx: Rerfactor use of sp context Quinn Tran (18): qla2xxx: Fix wrong IOCB type assumption. qla2xxx: Add DebugFS node of irq vector cpuid qla2xxx: Collect addtional debug data for FW qla2xxx: Fix crash due to null pointer access. qla2xxx: Refactore target code to remove symbol dependency qla2xxx: Refactor T10-DIF PI support qla2xxx: Add framework for Async fabric discovery. qla2xxx: Refactor session management code. qla2xxx: Add Dual mode support in the driver qla2xxx: Fix invalid handle erroneous message. qla2xxx: Add interrupt polling mechanism qla2xxx: Rename qlini_mode parameter qla2xxx: Improve RSCN handling in driver qla2xxx: Fix slow mem alloc behind lock qla2xxx: Reduce exess wait during chip reset qla2xxx: Allow relogin to go through if remote login did not finish qla2xxx: Improve submission of non critical MB interface. qla2xxx: Add check for corrupt ATIO. drivers/scsi/qla2xxx/qla_attr.c| 366 - drivers/scsi/qla2xxx/qla_bsg.c | 21 +- drivers/scsi/qla2xxx/qla_dbg.c |2 +- drivers/scsi/qla2xxx/qla_dbg.h |1 + drivers/scsi/qla2xxx/qla_def.h | 287 +++- drivers/scsi/qla2xxx/qla_dfs.c | 237 ++- drivers/scsi/qla2xxx/qla_fw.h | 107 +- drivers/scsi/qla2xxx/qla_gbl.h | 86 +- drivers/scsi/qla2xxx/qla_gs.c | 733 - drivers/scsi/qla2xxx/qla_init.c| 1604 +++- drivers/scsi/qla2xxx/qla_inline.h | 34 +- drivers/scsi/qla2xxx/qla_iocb.c| 172 ++- drivers/scsi/qla2xxx/qla_isr.c | 414 -- drivers/scsi/qla2xxx/qla_mbx.c | 553 +-- drivers/scsi/qla2xxx/qla_mid.c | 15 +- drivers/scsi/qla2xxx/qla_mr.c | 52 +- drivers/scsi/qla2xxx/qla_os.c | 454 -- drivers/scsi/qla2xxx/qla_target.c | 2890 +--- drivers/scsi/qla2xxx/qla_target.h | 257 ++-- drivers/scsi/qla2xxx/qla_tmpl.c| 24 + drivers/scsi/qla2xxx/tcm_qla2xxx.c | 753 -- drivers/scsi/qla2xxx/tcm_qla2xxx.h | 16 +- 22 files changed, 6658 insertions(+), 2420 deletions(-) -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 03/22] qla2xxx: Set tcm_qla2xxx version to automatically track qla2xxx version.
Signed-off-by: Himanshu Madhani Signed-off-by: Giridhar Malavali --- drivers/scsi/qla2xxx/tcm_qla2xxx.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/tcm_qla2xxx.h b/drivers/scsi/qla2xxx/tcm_qla2xxx.h index 37e026a..37e9f57 100644 --- a/drivers/scsi/qla2xxx/tcm_qla2xxx.h +++ b/drivers/scsi/qla2xxx/tcm_qla2xxx.h @@ -1,7 +1,7 @@ #include #include -#define TCM_QLA2XXX_VERSION"v0.1" +#define TCM_QLA2XXX_VERSIONQLA2XXX_VERSION /* length of ASCII WWPNs including pad */ #define TCM_QLA2XXX_NAMELEN32 /* -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 09/22] qla2xxx: Refactor T10-DIF PI support
From: Quinn Tran qla2xxx currently access T10-DIF protection opcode and type field in se_cmd struct. Add translation code so qla2xxx driver would not acces private TCM data structure. Signed-off-by: Quinn Tran Signed-off-by: Anil Gurumurthy Signed-off-by: Himanshu Madhani --- drivers/scsi/qla2xxx/qla_dbg.h | 1 + drivers/scsi/qla2xxx/qla_def.h | 23 ++ drivers/scsi/qla2xxx/qla_dfs.c | 15 + drivers/scsi/qla2xxx/qla_gbl.h | 6 +- drivers/scsi/qla2xxx/qla_init.c| 3 + drivers/scsi/qla2xxx/qla_inline.h | 17 + drivers/scsi/qla2xxx/qla_iocb.c| 17 +- drivers/scsi/qla2xxx/qla_isr.c | 3 + drivers/scsi/qla2xxx/qla_target.c | 613 - drivers/scsi/qla2xxx/qla_target.h | 47 ++- drivers/scsi/qla2xxx/tcm_qla2xxx.c | 158 -- 11 files changed, 661 insertions(+), 242 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h index e1fc4e6..c6bffe9 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.h +++ b/drivers/scsi/qla2xxx/qla_dbg.h @@ -348,6 +348,7 @@ void __attribute__((format (printf, 4, 5))) #define ql_dbg_tgt 0x4000 /* Target mode */ #define ql_dbg_tgt_mgt 0x2000 /* Target mode management */ #define ql_dbg_tgt_tmr 0x1000 /* Target mode task management */ +#define ql_dbg_tgt_dif 0x0800 /* Target mode dif */ extern int qla27xx_dump_mpi_ram(struct qla_hw_data *, uint32_t, uint32_t *, uint32_t, void **); diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 07cda5a..8cee332 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -2859,6 +2859,16 @@ struct qla_chip_state_84xx { uint32_t gold_fw_version; }; +struct qla_dif_statistics { + uint64_t dif_input_bytes; + uint64_t dif_output_bytes; + uint64_t dif_input_requests; + uint64_t dif_output_requests; + uint32_t dif_guard_err; + uint32_t dif_ref_tag_err; + uint32_t dif_app_tag_err; +}; + struct qla_statistics { uint32_t total_isp_aborts; uint64_t input_bytes; @@ -2871,6 +2881,7 @@ struct qla_statistics { uint32_t stat_max_pend_cmds; uint32_t stat_max_qfull_cmds_alloc; uint32_t stat_max_qfull_cmds_dropped; + struct qla_dif_statistics qla_dif_stats; }; struct bidi_statistics { @@ -2878,6 +2889,17 @@ struct bidi_statistics { unsigned long long transfer_bytes; }; +/* DIF */ +struct qla_tc_param { + struct scsi_qla_host*vha; + uint32_tblk_sz; + uint32_tbufflen; + struct scatterlist *sg; + struct scatterlist *prot_sg; + struct crc_context *ctx; + uint8_t *ctx_dsd_alloced; +}; + /* Multi queue support */ #define MBC_INITIALIZE_MULTIQ 0x1f #define QLA_QUE_PAGE 0X1000 @@ -3007,6 +3029,7 @@ struct qlt_hw_data { uint16_t atio_q_length; uint32_t __iomem *atio_q_in; uint32_t __iomem *atio_q_out; + uint64_tatio_ring_end_addr; struct qla_tgt_func_tmpl *tgt_ops; struct qla_tgt_cmd *cmds[DEFAULT_OUTSTANDING_COMMANDS]; diff --git a/drivers/scsi/qla2xxx/qla_dfs.c b/drivers/scsi/qla2xxx/qla_dfs.c index 6aa24ee..f69ff52 100644 --- a/drivers/scsi/qla2xxx/qla_dfs.c +++ b/drivers/scsi/qla2xxx/qla_dfs.c @@ -151,6 +151,21 @@ seq_printf(s, "num Q full sent = %lld\n", vha->tgt_counters.num_q_full_sent); +/* DIF stats */ + seq_printf(s, "DIF Inp Bytes = %lld\n", + vha->qla_stats.qla_dif_stats.dif_input_bytes); + seq_printf(s, "DIF Outp Bytes = %lld\n", + vha->qla_stats.qla_dif_stats.dif_output_bytes); + seq_printf(s, "DIF Inp Req = %lld\n", + vha->qla_stats.qla_dif_stats.dif_input_requests); + seq_printf(s, "DIF Outp Req = %lld\n", + vha->qla_stats.qla_dif_stats.dif_output_requests); + seq_printf(s, "DIF Guard err = %d\n", + vha->qla_stats.qla_dif_stats.dif_guard_err); + seq_printf(s, "DIF Ref tag err = %d\n", + vha->qla_stats.qla_dif_stats.dif_ref_tag_err); + seq_printf(s, "DIF App tag err = %d\n", + vha->qla_stats.qla_dif_stats.dif_app_tag_err); return 0; } diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 13c4d51..9303dbe 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -243,11 +243,11 @@ int qla2x00_marker(struct scsi_qla_host *, struct req_que *, struct rsp_que *, extern void *qla2x00_alloc_iocbs(scsi_qla_host_t *, srb_t *); extern int qla2x00_issue_marker(scsi_qla_host_t *, int); extern int qla24xx_walk_and_build_sglist_no_difb(struct qla_hw_data *, srb_t *, - uint32_t *, uint16_t, struct qla_tgt_cmd *); + uint32_t *, uint16_t, struct qla_tc_param *); extern int qla24xx_walk_and_build_sglist(struct qla_hw_data *, srb_t *, - uint32_t *, uint16
[PATCH 06/22] qla2xxx: Collect addtional debug data for FW
From: Quinn Tran Signed-off-by: Quinn Tran Signed-off-by: Himanshu Madhani --- drivers/scsi/qla2xxx/qla_mbx.c | 27 --- 1 file changed, 20 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index a94a3ab..76184ee 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c @@ -318,20 +318,33 @@ static int is_rom_cmd(uint16_t cmd) } } else { - uint16_t mb0; - uint32_t ictrl; + uint16_t mb[8]; + uint32_t ictrl, host_status, hccr; uint16_tw; if (IS_FWI2_CAPABLE(ha)) { - mb0 = RD_REG_WORD(®->isp24.mailbox0); + mb[0] = RD_REG_WORD(®->isp24.mailbox0); + mb[1] = RD_REG_WORD(®->isp24.mailbox1); + mb[2] = RD_REG_WORD(®->isp24.mailbox2); + mb[3] = RD_REG_WORD(®->isp24.mailbox3); + mb[7] = RD_REG_WORD(®->isp24.mailbox7); ictrl = RD_REG_DWORD(®->isp24.ictrl); + host_status = RD_REG_DWORD(®->isp24.host_status); + hccr = RD_REG_DWORD(®->isp24.hccr); + + ql_log(ql_log_warn, vha, 0x1119, + "MBX Command timeout for cmd %x, iocontrol=%x jiffies=%lx " + "mb[0-3]=[0x%x 0x%x 0x%x 0x%x] mb7 0x%x host_status 0x%x hccr 0x%x\n", + command, ictrl, jiffies, mb[0], mb[1], mb[2], mb[3], + mb[7], host_status, hccr); + } else { - mb0 = RD_MAILBOX_REG(ha, ®->isp, 0); + mb[0] = RD_MAILBOX_REG(ha, ®->isp, 0); ictrl = RD_REG_WORD(®->isp.ictrl); + ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1119, + "MBX Command timeout for cmd %x, iocontrol=%x jiffies=%lx " + "mb[0]=0x%x\n", command, ictrl, jiffies, mb[0]); } - ql_dbg(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1119, - "MBX Command timeout for cmd %x, iocontrol=%x jiffies=%lx " - "mb[0]=0x%x\n", command, ictrl, jiffies, mb0); ql_dump_regs(ql_dbg_mbx + ql_dbg_buffer, vha, 0x1019); /* Capture FW dump only, if PCI device active */ -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 10/22] qla2xxx: Add framework for Async fabric discovery.
From: Quinn Tran Currently code makes login/logout decision after a full scan of the fabric. It's an expensive process in a large SAN. Eliminate duplication of command by moving the login/logout decision from a full fabric scan to an individual scan of the affected port. Also, current code ignore the completion of the NACK. This patch also attempts to optimize exepsive fabric discovery process by optimizing the process of scanning switch for affected port when RSCN is received. This patch adds following capabilities in the driver - Send Notification Acknowledgement asynchronously. - Update session/fcport state asynchronously. - Create a session or fcport struct asynchronously. - Send GNL asynchronously. The command will ask FW to provide a list of FC Port entries FW knows about. - Send GPDB asynchronously. The command will ask FW to provide detail data of an FC Port FW knows about or perform ADISC to verify the state of the session. - Send GPNID asynchronously. The command will ask switch to provide WWPN for provided NPort ID. - Send GPSC asynchronously. The command will ask switch to provide registered port speed for provided WWPN. - Send GIDPN asynchronously. The command will ask the switch to provide Nport ID for provided WWPN. Signed-off-by: Quinn Tran Signed-off-by: Himanshu Madhani --- drivers/scsi/qla2xxx/qla_attr.c |3 + drivers/scsi/qla2xxx/qla_def.h| 169 - drivers/scsi/qla2xxx/qla_fw.h | 30 + drivers/scsi/qla2xxx/qla_gbl.h| 58 +- drivers/scsi/qla2xxx/qla_gs.c | 687 +-- drivers/scsi/qla2xxx/qla_init.c | 1346 - drivers/scsi/qla2xxx/qla_inline.h |7 +- drivers/scsi/qla2xxx/qla_iocb.c | 74 +- drivers/scsi/qla2xxx/qla_isr.c| 221 -- drivers/scsi/qla2xxx/qla_mbx.c| 88 --- drivers/scsi/qla2xxx/qla_os.c | 184 +++-- drivers/scsi/qla2xxx/qla_target.c | 226 ++- drivers/scsi/qla2xxx/qla_target.h | 17 +- 13 files changed, 2493 insertions(+), 617 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 47eb4d5..f48b76c 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -2156,6 +2156,9 @@ struct device_attribute *qla2x00_host_attrs[] = { clear_bit(vha->vp_idx, ha->vp_idx_map); mutex_unlock(&ha->vport_lock); + dma_free_coherent(&ha->pdev->dev, + vha->gnl.size, vha->gnl.l, vha->gnl.ldma); + if (vha->qpair->vp_idx == vha->vp_idx) { if (qla2xxx_delete_qpair(vha, vha->qpair) != QLA_SUCCESS) ql_log(ql_log_warn, vha, 0x7087, diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 8cee332..f281f3d 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -55,6 +55,8 @@ #include "qla_settings.h" +#define MODE_DUAL (MODE_TARGET|MODE_INITIATOR) + /* * Data bit definitions */ @@ -251,6 +253,14 @@ #define MAX_CMDSZ 16 /* SCSI maximum CDB size. */ #include "qla_fw.h" + +struct name_list_extended { + struct get_name_list_extended *l; + dma_addr_t ldma; + struct list_head fcports; /* protect by sess_list */ + u32 size; + u8 sent; +}; /* * Timeout timer counts in seconds */ @@ -309,6 +319,17 @@ struct els_logo_payload { uint8_t wwpn[WWN_SIZE]; }; +struct ct_arg { + void *iocb; + u16 nport_handle; + dma_addr_t req_dma; + dma_addr_t rsp_dma; + u32 req_size; + u32 rsp_size; + void *req; + void *rsp; +}; + /* * SRB extensions. */ @@ -320,6 +341,7 @@ struct srb_iocb { #define SRB_LOGIN_COND_PLOGI BIT_1 #define SRB_LOGIN_SKIP_PRLIBIT_2 uint16_t data[2]; + u32 iop[2]; } logio; struct { #define ELS_DCMD_TIMEOUT 20 @@ -372,6 +394,16 @@ struct srb_iocb { __le16 comp_status; struct completion comp; } abt; + struct ct_arg ctarg; + struct { + __le16 in_mb[28]; /* fr fw */ + __le16 out_mb[28]; /* to fw */ + void *out, *in; + dma_addr_t out_dma, in_dma; + } mbx; + struct { + struct imm_ntfy_from_isp *ntfy; + } nack; } u; struct timer_list timer; @@ -392,16 +424,24 @@ struct srb_iocb { #define SRB_FXIOCB_BCMD11 #define SRB_ABT_CMD12 #define SRB_ELS_DCMD 13 +#define SRB_MB_IOCB14 +#define SRB_CT_PTHRU_CMD 15 +#define SRB_NACK_PLOGI 16 +#define SRB_NACK_PRLI 17 +#define SRB_NACK_LOGO 18 typedef struct srb { atomic_t ref_count; struct fc_port *fcport; + void *vha; uint32_t handle; uint16_t flags; uint16_t type; char *na
[PATCH 07/22] qla2xxx: Fix crash due to null pointer access.
From: Quinn Tran This patch fixes crash due to Null pointer access. Following stack trace will be seen. [1469877.797315] Call Trace: [1469877.799940] [] qla2x00_mem_alloc+0xb09/0x10c0 [qla2xxx] [1469877.806980] [] qla2x00_probe_one+0x86a/0x1b50 [qla2xxx] [1469877.814013] [] ? __pm_runtime_resume+0x51/0xa0 [1469877.820265] [] ? _raw_spin_lock_irqsave+0x25/0x90 [1469877.826776] [] ? _raw_spin_unlock_irqrestore+0x6d/0x80 [1469877.833720] [] ? preempt_count_sub+0xb1/0x100 [1469877.839885] [] ? _raw_spin_unlock_irqrestore+0x4c/0x80 [1469877.846830] [] local_pci_probe+0x4c/0xb0 [1469877.852562] [] ? preempt_count_sub+0xb1/0x100 [1469877.858727] [] pci_call_probe+0x89/0xb0 Signed-off-by: Quinn Tran Signed-off-by: Himanshu Madhani --- drivers/scsi/qla2xxx/qla_os.c | 23 +++ 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 544f957..ce8c1dd 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -3681,7 +3681,7 @@ void qla2x00_mark_device_lost(scsi_qla_host_t *vha, fc_port_t *fcport, sizeof(struct ct6_dsd), 0, SLAB_HWCACHE_ALIGN, NULL); if (!ctx_cachep) - goto fail_free_gid_list; + goto fail_free_srb_mempool; } ha->ctx_mempool = mempool_create_slab_pool(SRB_MIN_REQ, ctx_cachep); @@ -3834,7 +3834,7 @@ void qla2x00_mark_device_lost(scsi_qla_host_t *vha, fc_port_t *fcport, ha->loop_id_map = kzalloc(BITS_TO_LONGS(LOOPID_MAP_SIZE) * sizeof(long), GFP_KERNEL); if (!ha->loop_id_map) - goto fail_async_pd; + goto fail_loop_id_map; else { qla2x00_set_reserved_loop_ids(ha); ql_dbg_pci(ql_dbg_init, ha->pdev, 0x0123, @@ -3843,10 +3843,15 @@ void qla2x00_mark_device_lost(scsi_qla_host_t *vha, fc_port_t *fcport, return 0; +fail_loop_id_map: + dma_pool_free(ha->s_dma_pool, ha->async_pd, ha->async_pd_dma); + ha->async_pd = NULL; fail_async_pd: dma_pool_free(ha->s_dma_pool, ha->ex_init_cb, ha->ex_init_cb_dma); + ha->ex_init_cb = NULL; fail_ex_init_cb: kfree(ha->npiv_info); + ha->npiv_info = NULL; fail_npiv_info: dma_free_coherent(&ha->pdev->dev, ((*rsp)->length + 1) * sizeof(response_t), (*rsp)->ring, (*rsp)->dma); @@ -3870,6 +3875,14 @@ void qla2x00_mark_device_lost(scsi_qla_host_t *vha, fc_port_t *fcport, dma_pool_free(ha->s_dma_pool, ha->ms_iocb, ha->ms_iocb_dma); ha->ms_iocb = NULL; ha->ms_iocb_dma = 0; + + if (ha->sns_cmd) { + dma_free_coherent(&ha->pdev->dev, sizeof(struct sns_cmd_pkt), + ha->sns_cmd, ha->sns_cmd_dma); + ha->sns_cmd_dma = 0; + ha->sns_cmd = NULL; + } + fail_dma_pool: if (IS_QLA82XX(ha) || ql2xenabledif) { dma_pool_destroy(ha->fcp_cmnd_dma_pool); @@ -3887,10 +3900,12 @@ void qla2x00_mark_device_lost(scsi_qla_host_t *vha, fc_port_t *fcport, kfree(ha->nvram); ha->nvram = NULL; fail_free_ctx_mempool: - mempool_destroy(ha->ctx_mempool); + if (ha->ctx_mempool) + mempool_destroy(ha->ctx_mempool); ha->ctx_mempool = NULL; fail_free_srb_mempool: - mempool_destroy(ha->srb_mempool); + if (ha->srb_mempool) + mempool_destroy(ha->srb_mempool); ha->srb_mempool = NULL; fail_free_gid_list: dma_free_coherent(&ha->pdev->dev, qla2x00_gid_list_size(ha), -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 08/22] qla2xxx: Refactore target code to remove symbol dependency
From: Quinn Tran Following changes are done for target code - Move cmd search out of qla to remove symbol dependency. The command list is held in se_session struct. This knowledege should be in tcm_qla2xxx. - Move code that "convert Task Mgmt Command flags fr ATIO to TCM #define" from qla2xx driver to tcm_qla2xxx driver. - Move percpu_ida_alloc/free to tcm_qla2xxx - Refactor sess_kref handling as driver does not access se_session often. Remove se_session internal knowledge from qla2xxx as tcm_qla2xxx is the only one that have this knowledge. - Move Command residual check from qla2xxx to tcm_qla2xxx - qla2xxx currently access t_task_cdb/t_task_lba field in se_cmd struct. Remove access of TCM's private data struct. - Remove direct access of scsi_status field in se_cmd - Remove se_cmd from qlt_do_ctio_completion - Remove se_cmd access in srr code section - Move se_cmd struct outside of qla_tgt_cmd/qla_tgt_mgmt_cmd. - To convert the pointer from one struct to another, new inline functions was added to take care of the convertion. - Allow target driver to handle MBA_REJECTED_FCP_CMD AEN 8049. This will allow driver to gracefully handle reaching the exchange limit if desired. Ideally, we could track each NPORT that we are caching by LRU time and logout the oldest handle. - Moves allocation/free mechanism for task management commands to TCM shim driver layer. - Merge qla_tgt_sess into struct fc_port structures Signed-off-by: Quinn Tran Signed-off-by: Himanshu Madhani --- drivers/scsi/qla2xxx/qla_bsg.c | 8 +- drivers/scsi/qla2xxx/qla_def.h | 34 ++ drivers/scsi/qla2xxx/qla_dfs.c | 10 +- drivers/scsi/qla2xxx/qla_gbl.h | 1 + drivers/scsi/qla2xxx/qla_init.c| 26 +- drivers/scsi/qla2xxx/qla_iocb.c| 7 +- drivers/scsi/qla2xxx/qla_isr.c | 8 +- drivers/scsi/qla2xxx/qla_mid.c | 3 + drivers/scsi/qla2xxx/qla_mr.c | 12 +- drivers/scsi/qla2xxx/qla_os.c | 10 +- drivers/scsi/qla2xxx/qla_target.c | 793 - drivers/scsi/qla2xxx/qla_target.h | 157 +++- drivers/scsi/qla2xxx/tcm_qla2xxx.c | 588 --- drivers/scsi/qla2xxx/tcm_qla2xxx.h | 14 +- 14 files changed, 855 insertions(+), 816 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c index 1bf8061..cdf0dce 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.c +++ b/drivers/scsi/qla2xxx/qla_bsg.c @@ -61,7 +61,7 @@ if (sp->type == SRB_CT_CMD || sp->type == SRB_FXIOCB_BCMD || sp->type == SRB_ELS_CMD_HST) - kfree(sp->fcport); + qla2x00_free_fcport(sp->fcport); qla2x00_rel_sp(vha, sp); } @@ -409,7 +409,7 @@ done_free_fcport: if (bsg_request->msgcode == FC_BSG_RPT_ELS) - kfree(fcport); + qla2x00_free_fcport(fcport); done: return rval; } @@ -549,7 +549,7 @@ return rval; done_free_fcport: - kfree(fcport); + qla2x00_free_fcport(fcport); done_unmap_sg: dma_unmap_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list, bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE); @@ -2052,7 +2052,7 @@ return rval; done_free_fcport: - kfree(fcport); + qla2x00_free_fcport(fcport); done_unmap_rsp_sg: if (piocb_rqst->flags & SRB_FXDISC_RESP_DMA_VALID) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 1e3a3fa..07cda5a 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -1793,6 +1793,7 @@ struct crc_context { #define SS_RESIDUAL_OVER BIT_10 #define SS_SENSE_LEN_VALID BIT_9 #define SS_RESPONSE_INFO_LEN_VALID BIT_8 +#define SS_SCSI_STATUS_BYTE0xff #define SS_RESERVE_CONFLICT(BIT_4 | BIT_3) #define SS_BUSY_CONDITION BIT_3 @@ -2033,6 +2034,20 @@ struct mbx_entry { FCT_TARGET } fc_port_type_t; +typedef enum { + QLT_PLOGI_LINK_SAME_WWN, + QLT_PLOGI_LINK_CONFLICT, + QLT_PLOGI_LINK_MAX +} qlt_plogi_link_t; + +typedef struct { + struct list_headlist; + u8 iocb[64]; /* imm_ntfy_from_isp */ + port_id_t id; + int ref_count; +} qlt_plogi_ack_t; + + /* * Fibre channel port structure. */ @@ -2046,6 +2061,25 @@ struct mbx_entry { uint16_t loop_id; uint16_t old_loop_id; + unsigned int conf_compl_supported:1; + unsigned int deleted:2; + unsigned int local:1; + unsigned int logout_on_delete:1; + unsigned int keep_nport_handle:1; + unsigned int send_els_logo:1; + + unsigned char logout_completed; + int generation; + + void *se_sess; + struct kref sess_kref; + struct qla_tgt *tgt; + unsigned long expires; + struct list_head del_list_entry; + struct work_struct free_work; + + qlt_plogi_ack_t *plogi_link[QLT_PLOGI_LINK_
[PATCH 04/22] qla2xxx: Clear BIT 15 in NVRAM during initialization.
Some of the ports have BIT_15 of firmware_options1 set. This is a reserved bit and should not be set for Target Mode. Clear BIT 15 during stage1 initialization. Signed-off-by: Himanshu Madhani Signed-off-by: Giridhar Malavali --- drivers/scsi/qla2xxx/qla_target.c | 15 ++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index 8a762a6..adb3b93 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -6527,7 +6527,6 @@ static void qlt_disable_vha(struct scsi_qla_host *vha) /* Disable ini mode, if requested */ if (!qla_ini_mode_enabled(vha)) nv->firmware_options_1 |= cpu_to_le32(BIT_5); - /* Disable Full Login after LIP */ nv->firmware_options_1 &= cpu_to_le32(~BIT_13); /* Enable initial LIP */ @@ -6541,6 +6540,13 @@ static void qlt_disable_vha(struct scsi_qla_host *vha) /* Disable Full Login after LIP */ nv->host_p &= cpu_to_le32(~BIT_10); + + /* +* clear BIT 15 explicitly as we have seen at least +* a couple of instances where this was set and this +* was causing the firmware to not be initialized. +*/ + nv->firmware_options_1 &= __constant_cpu_to_le32(~BIT_15); /* Enable target PRLI control */ nv->firmware_options_2 |= cpu_to_le32(BIT_14); } else { @@ -6630,6 +6636,13 @@ static void qlt_disable_vha(struct scsi_qla_host *vha) nv->firmware_options_1 &= cpu_to_le32(~BIT_13); /* Enable initial LIP */ nv->firmware_options_1 &= cpu_to_le32(~BIT_9); + /* +* clear BIT 15 explicitly as we have seen at +* least a couple of instances where this was set +* and this was causing the firmware to not be +* initialized. +*/ + nv->firmware_options_1 &= __constant_cpu_to_le32(~BIT_15); if (ql2xtgt_tape_enable) /* Enable FC tape support */ nv->firmware_options_2 |= cpu_to_le32(BIT_12); -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 16/22] qla2xxx: Improve RSCN handling in driver
From: Quinn Tran - Save NPort ID early in link init. - Add session deletion for TPRLO and send acknowledgement for TPRLO. - Enable FW option to move ABTS, RIDA & PUREX from RSPQ to ATIOQ. - Move ABTS & RIDA to ATIOQ helps in keeping command ordering and link up sequence ordering. - Save Nport ID and update VP map so that SCSI CMD/ATIO won't be dropped. - fcport alloc does the initializes memory to zero. Remove memset to zero since It migth corrupt link list. - Turn off Registration for State Change MB in loop mode. Current code blindly do State Change Registration when the link is up. Move SCR behind fabric scan, so AL case would not get erroneous error message. Signed-off-by: Quinn Tran Signed-off-by: Himanshu Madhani --- drivers/scsi/qla2xxx/qla_def.h| 12 +- drivers/scsi/qla2xxx/qla_fw.h | 59 +++--- drivers/scsi/qla2xxx/qla_gbl.h| 2 + drivers/scsi/qla2xxx/qla_gs.c | 4 +- drivers/scsi/qla2xxx/qla_init.c | 150 drivers/scsi/qla2xxx/qla_isr.c| 6 +- drivers/scsi/qla2xxx/qla_mbx.c| 123 drivers/scsi/qla2xxx/qla_os.c | 48 drivers/scsi/qla2xxx/qla_target.c | 237 ++ 9 files changed, 501 insertions(+), 140 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 85beab6..f9a4528 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -2141,6 +2141,14 @@ enum fcport_mgt_event { FCME_DELETE_DONE, }; +enum rscn_addr_format { + RSCN_PORT_ADDR, + RSCN_AREA_ADDR, + RSCN_DOM_ADDR, + RSCN_FAB_ADDR, +}; + + /* * Fibre channel port structure. */ @@ -3907,7 +3915,7 @@ struct qla_tgt_counters { #define FCOE_CTX_RESET_NEEDED 18 /* Initiate FCoE context reset */ #define MPI_RESET_NEEDED 19 /* Initiate MPI FW reset */ #define ISP_QUIESCE_NEEDED 20 /* Driver need some quiescence */ -#define SCR_PENDING21 /* SCR in target mode */ +#define FREE_BIT 21 #define PORT_UPDATE_NEEDED 22 #define FX00_RESET_RECOVERY23 #define FX00_TARGET_SCAN 24 @@ -3961,7 +3969,9 @@ struct qla_tgt_counters { /* list of commands waiting on workqueue */ struct list_headqla_cmd_list; struct list_headqla_sess_op_cmd_list; + struct list_head unknown_atio_list; spinlock_t cmd_list_lock; + struct delayed_work unknown_atio_work; /* Counter to detect races between ELS and RSCN events */ atomic_tgeneration_tick; diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h index 00938f1..6f3439c 100644 --- a/drivers/scsi/qla2xxx/qla_fw.h +++ b/drivers/scsi/qla2xxx/qla_fw.h @@ -1300,27 +1300,60 @@ struct vp_config_entry_24xx { }; #define VP_RPT_ID_IOCB_TYPE0x32/* Report ID Acquisition entry. */ +enum VP_STATUS { + VP_STAT_COMPL, + VP_STAT_FAIL, + VP_STAT_ID_CHG, + VP_STAT_SNS_TO, /* timeout */ + VP_STAT_SNS_RJT, + VP_STAT_SCR_TO, /* timeout */ + VP_STAT_SCR_RJT, +}; + +enum VP_FLAGS { + VP_FLAGS_CON_FLOOP = 1, + VP_FLAGS_CON_P2P = 2, + VP_FLAGS_CON_FABRIC = 3, + VP_FLAGS_NAME_VALID = BIT_5, +}; + struct vp_rpt_id_entry_24xx { uint8_t entry_type; /* Entry type. */ uint8_t entry_count;/* Entry count. */ uint8_t sys_define; /* System defined. */ uint8_t entry_status; /* Entry Status. */ - - uint32_t handle;/* System handle. */ - - uint16_t vp_count; /* Format 0 -- | VP setup | VP acq |. */ - /* Format 1 -- | VP count |. */ - uint16_t vp_idx;/* Format 0 -- Reserved. */ - /* Format 1 -- VP status and index. */ + uint32_t resv1; + uint8_t vp_acquired; + uint8_t vp_setup; + uint8_t vp_idx; /* Format 0=reserved */ + uint8_t vp_status; /* Format 0=reserved */ uint8_t port_id[3]; uint8_t format; - - uint8_t vp_idx_map[16]; - - uint8_t reserved_4[24]; - uint16_t bbcr; - uint8_t reserved_5[6]; + union { + struct { + /* format 0 loop */ + uint8_t vp_idx_map[16]; + uint8_t reserved_4[32]; + } f0; + struct { + /* format 1 fabric */ + uint8_t vpstat1_subcode;/* vp_status=1 subcode */ + uint8_t flags; + uint16_t fip_flags; + uint8_t rsv2[12]; + + uint8_t ls_rjt_vendor; + uint8_t ls_rjt_explanation; + uint8_t ls_rjt_reason; +
[PATCH 18/22] qla2xxx: Fix slow mem alloc behind lock
From: Quinn Tran In Some instance following stack trace is seen for slow memory allocation with lock held Call Trace: [] dump_stack+0x6b/0xa4 [] ? print_irqtrace_events+0xd0/0xe0 [] ___might_sleep+0x183/0x240 [] __might_sleep+0x52/0x90 [] kmem_cache_alloc_trace+0x5b/0x300 [] ? __lock_acquired+0x30b/0x420 [] qla2x00_alloc_fcport+0x38/0x2a0 [qla2xxx] [] ? qla2x00_do_work+0x34/0x2b0 [qla2xxx] [] ? _raw_spin_lock_irqsave+0x7b/0x90 [] ? qla24xx_create_new_sess+0x3a/0x160 [qla2xxx] [] qla24xx_create_new_sess+0xc3/0x160 [qla2xxx] [] ? trace_hardirqs_on+0xd/0x10 [] qla2x00_do_work+0x138/0x2b0 [qla2xxx] Signed-off-by: Quinn Tran Signed-off-by: Himanshu Madhani --- drivers/scsi/qla2xxx/qla_gbl.h| 1 + drivers/scsi/qla2xxx/qla_os.c | 35 ++- drivers/scsi/qla2xxx/qla_target.c | 11 +-- 3 files changed, 40 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 2e28b3f..9489a1c 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -143,6 +143,7 @@ int qla24xx_post_newsess_work(struct scsi_qla_host *, port_id_t *, extern int ql_dm_tgt_ex_pct; extern struct workqueue_struct *qla_wq; extern int ql2xmvasynctoatio; +extern struct kmem_cache *qla_tgt_plogi_cachep; extern int qla2x00_loop_reset(scsi_qla_host_t *); diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index 87dc64a..8137238 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c @@ -4486,8 +4486,9 @@ int qla24xx_post_upd_fcport_work(struct scsi_qla_host *vha, fc_port_t *fcport) void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e) { unsigned long flags; - fc_port_t *fcport = NULL; + fc_port_t *fcport = NULL, *tfcp; qlt_plogi_ack_t *pla = (qlt_plogi_ack_t *)e->u.new_sess.pla; + uint8_t free_fcport = 0; spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); fcport = qla2x00_find_fcport_by_wwpn(vha, e->u.new_sess.port_name, 1); @@ -4502,6 +4503,8 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e) pla->ref_count--; } } else { + spin_unlock_irqrestore(&vha->hw->tgt.sess_lock, flags); + fcport = qla2x00_alloc_fcport(vha, GFP_KERNEL); if (fcport) { fcport->d_id = e->u.new_sess.id; @@ -4511,6 +4514,30 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e) memcpy(&fcport->port_name, e->u.new_sess.port_name, WWN_SIZE); + } else { + ql_dbg(ql_dbg_disc, vha, 0x, + "%s %8phC mem alloc fail.\n", + __func__, e->u.new_sess.port_name); + + if (pla) + kmem_cache_free(qla_tgt_plogi_cachep, pla); + return; + } + + spin_lock_irqsave(&vha->hw->tgt.sess_lock, flags); + /* search again to make sure one else got ahead */ + tfcp = qla2x00_find_fcport_by_wwpn(vha, + e->u.new_sess.port_name, 1); + if (tfcp) { + /* should rarily happen */ + ql_dbg(ql_dbg_disc, vha, 0x, + "%s %8phC found existing fcport b4 add. DS %d LS %d\n", + __func__, tfcp->port_name, tfcp->disc_state, + tfcp->fw_login_state); + + free_fcport = 1; + } else { + list_add_tail(&fcport->list, &vha->vp_fcports); if (pla) { @@ -4527,6 +4554,12 @@ void qla24xx_create_new_sess(struct scsi_qla_host *vha, struct qla_work_evt *e) else qla24xx_async_gnl(vha, fcport); } + + if (free_fcport) { + qla2x00_free_fcport(fcport); + if (pla) + kmem_cache_free(qla_tgt_plogi_cachep, pla); + } } void diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index 54a5337..8a4b506 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -49,13 +49,12 @@ module_param(qlop_mode, charp, S_IRUGO); MODULE_PARM_DESC(qlop_mode, "Determines operating mode. Possible values: " - "\"exclusive\" - initiator mode will be enabled on load, " - "disabled on enabling target mode and then on disabling target mode " - "enabled back; " + "\"exclusive\" - Initiator Mode will be enabled on load. " + " Target Mode can be activated when ready. Only one mode can be active at a time; " "\"tgt_mode\" - Target mode only. Initiator mode wil
[PATCH 12/22] qla2xxx: Add Dual mode support in the driver
From: Quinn Tran Add switch to allow both Initiator Mode & Target mode to operate at the same time. Also remove unwanted/unused ini_mode_force option Signed-off-by: Quinn Tran Signed-off-by: Himanshu Madhani --- drivers/scsi/qla2xxx/qla_def.h | 2 +- drivers/scsi/qla2xxx/qla_init.c| 8 +-- drivers/scsi/qla2xxx/qla_isr.c | 19 +- drivers/scsi/qla2xxx/qla_target.c | 129 + drivers/scsi/qla2xxx/qla_target.h | 15 ++--- drivers/scsi/qla2xxx/tcm_qla2xxx.c | 2 +- 6 files changed, 131 insertions(+), 44 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 6370aca..6bf7ff9 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -3175,7 +3175,6 @@ struct qlt_hw_data { /* Protected by hw lock */ uint32_t enable_class_2:1; uint32_t enable_explicit_conf:1; - uint32_t ini_mode_force_reverse:1; uint32_t node_name_set:1; dma_addr_t atio_dma;/* Physical address. */ @@ -3328,6 +3327,7 @@ struct qla_hw_data { #define FLOGI_SP_SUPPORTBIT_13 uint8_t port_no;/* Physical port of adapter */ + uint8_t exch_starvation; /* Timeout timers. */ uint8_t loop_down_abort_time;/* port down timer */ diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index cfdfb02..df6a51f 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -813,9 +813,9 @@ void qla24xx_handle_gpdb_event(scsi_qla_host_t *vha, struct event_arg *ea) fcport->flags &= ~FCF_ASYNC_SENT; ql_dbg(ql_dbg_disc, vha, 0x, - "%s %8phC DS %d LS %d \n", + "%s %8phC DS %d LS %d rval %d \n", __func__, fcport->port_name, fcport->disc_state, - fcport->fw_login_state); + fcport->fw_login_state, rval); if (ea->sp->gen2 != fcport->login_gen) { /* target side must have changed it. */ @@ -4020,7 +4020,8 @@ static void qla2xxx_nvram_wwn_from_ofw(scsi_qla_host_t *vha, nvram_t *nv) * Process any ATIO queue entries that came in * while we weren't online. */ - if (qla_tgt_mode_enabled(vha)) { + if (qla_tgt_mode_enabled(vha) || + qla_dual_mode_enabled(vha)) { if (IS_QLA27XX(ha) || IS_QLA83XX(ha)) { spin_lock_irqsave(&ha->tgt.atio_lock, flags); @@ -5739,7 +5740,6 @@ int qla2x00_perform_loop_resync(scsi_qla_host_t *ha) if (!status) { /* Issue a marker after FW becomes ready. */ qla2x00_marker(vha, req, rsp, 0, 0, MK_SYNC_ALL); - set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); } diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 7a7a8c6..04899f4 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -1029,7 +1029,8 @@ static void qla_irq_affinity_notify(struct irq_affinity_notify *, qla2x00_mark_all_devices_lost(vha, 1); - if (vha->vp_idx == 0 && !qla_ini_mode_enabled(vha)) + if (vha->vp_idx == 0 && + (qla_tgt_mode_enabled(vha) || qla_dual_mode_enabled(vha))) set_bit(SCR_PENDING, &vha->dpc_flags); set_bit(LOOP_RESYNC_NEEDED, &vha->dpc_flags); @@ -1648,6 +1649,7 @@ static void qla_irq_affinity_notify(struct irq_affinity_notify *, fcport->d_id.b.area, fcport->d_id.b.al_pa, le32_to_cpu(logio->io_parameter[0])); + vha->hw->exch_starvation = 0; data[0] = MBS_COMMAND_COMPLETE; if (sp->type != SRB_LOGIN_CMD) goto logio_done; @@ -1683,6 +1685,21 @@ static void qla_irq_affinity_notify(struct irq_affinity_notify *, case LSC_SCODE_NPORT_USED: data[0] = MBS_LOOP_ID_USED; break; + case LSC_SCODE_NOXCB: + vha->hw->exch_starvation++; + if (vha->hw->exch_starvation > 5) { + ql_log(ql_log_warn, vha, 0x, + "Exchange starvation. Reseting RISC\n"); + + vha->hw->exch_starvation = 0; + + if (IS_P3P_TYPE(vha->hw)) + set_bit(FCOE_CTX_RESET_NEEDED, &vha->dpc_flags); + else + set_bit(ISP_ABORT_NEEDED, &vha->dpc_flags); + qla2xxx_wake_dpc(vha); + } + /* drop through */ default: data[0] = MBS_COMMAND_ERROR;
[PATCH 13/22] qla2xxx: Fix invalid handle erroneous message.
From: Quinn Tran Termination of Immediate Notification IOCB was using wrong IOCB handle. IOCB completion code was unable to find appropriate code path due to wrong handle. Following message is seen in the logs. "Error entry - invalid handle/queue ()." Signed-off-by: Quinn Tran Signed-off-by: Himanshu Madhani --- drivers/scsi/qla2xxx/qla_isr.c| 9 + drivers/scsi/qla2xxx/qla_target.c | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 04899f4..c7f73b1 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -2630,6 +2630,15 @@ struct scsi_dif_tuple { if (pkt->entry_status & RF_BUSY) res = DID_BUS_BUSY << 16; + if ((pkt->entry_type == NOTIFY_ACK_TYPE) && + (pkt->handle == QLA_TGT_SKIP_HANDLE)) { + /* There are some NACK that uses the SP method and +* some are not using the SP method of sending. filter +* NACK here to prevent erroneous err. +*/ + return; + } + sp = qla2x00_get_sp_from_handle(vha, func, req, pkt); if (sp) { sp->done(vha, sp, res); diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index 8ccbd74..e6b2a45 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -3344,7 +3344,7 @@ static int __qlt_send_term_imm_notif(struct scsi_qla_host *vha, pkt->entry_type = NOTIFY_ACK_TYPE; pkt->entry_count = 1; - pkt->handle = QLA_TGT_SKIP_HANDLE | CTIO_COMPLETION_HANDLE_MARK; + pkt->handle = QLA_TGT_SKIP_HANDLE; nack = (struct nack_to_isp *)pkt; nack->ox_id = ntfy->ox_id; -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 15/22] qla2xxx: Rename qlini_mode parameter
From: Quinn Tran Qlogic's adapter is able to behave in multiple modes: initiator, target, exclusive/either, and dual/both. This patch renames the qlini_mode -> qlop_mode and allow different setting for each port and exchange resource control. Usage: modprobe qla2xxx qlop_mode=dual_mode echo 95 > /sys/class/scsi_host//ql_dm_tgt_ex_pct echo dual_mode > /sys/class/scsi_host//f_qlop_mode echo ini_mode > /sys/class/scsi_host//f_qlop_mode Signed-off-by: Quinn Tran Signed-off-by: Himanshu Madhani --- drivers/scsi/qla2xxx/qla_attr.c | 351 ++ drivers/scsi/qla2xxx/qla_def.h| 4 + drivers/scsi/qla2xxx/qla_gbl.h| 4 + drivers/scsi/qla2xxx/qla_os.c | 4 + drivers/scsi/qla2xxx/qla_target.c | 117 ++--- drivers/scsi/qla2xxx/qla_target.h | 22 +-- 6 files changed, 425 insertions(+), 77 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index f48b76c..d8b77aa 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -1504,6 +1504,351 @@ ha->pep_version[0], ha->pep_version[1], ha->pep_version[2]); } + +static ssize_t +qla2x00_tgt_ex_pct_show(struct device *dev, struct device_attribute *attr, +char *buf) +{ + scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); + int len = 0; + + if (ql2x_op_mode == QLA2XXX_OP_MODE_INITIATOR) { + len += scnprintf(buf + len, PAGE_SIZE-len, + "This option is not supported. Driver need to be loaded with " + "non-initiator mode (qlop_mode)"); + return len; + } + + len += scnprintf(buf + len, PAGE_SIZE-len, + "target exchange percentage: new %d : current: %d\n\n", + vha->u_tgt_ex_pct, vha->tgt_ex_pct); + + len += scnprintf(buf + len, PAGE_SIZE-len, + "Please (re)set operating mode via \"f_qlop_mode\" to load new setting\n"); + return len; +} + +static ssize_t +qla2x00_tgt_ex_pct_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) +{ + scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); + int val = 0; + + if (ql2x_op_mode == QLA2XXX_OP_MODE_INITIATOR) + goto out; + + if (sscanf(buf, "%d", &val) != 1) + return -EINVAL; + + if (val > 100) + val = 100; + else if (val < 0) + val = 0; + + vha->u_tgt_ex_pct = val; +out: + return strlen(buf); +} + +static ssize_t +qla2x00_opmode_show(struct device *dev, struct device_attribute *attr, +char *buf) +{ + scsi_qla_host_t *vha = shost_priv(class_to_shost(dev)); + int len = 0; + + if (ql2x_op_mode == QLA2XXX_OP_MODE_INITIATOR) { + len += scnprintf(buf + len, PAGE_SIZE-len, + "This option is not supported. Driver need to be loaded with " + "non-initiator mode (qlop_mode)"); + return len; + } + + len += scnprintf(buf + len, PAGE_SIZE-len, + "Supported options: exclusive | tgt_mode | ini_mode | dual_mode\n"); + + /* --- */ + len += scnprintf(buf + len, PAGE_SIZE-len, "Current selection: "); + + switch (vha->qlop_mode) { + case QLA2XXX_OP_MODE_EXCLUSIVE: + len += scnprintf(buf + len, PAGE_SIZE-len, + QLA2XXX_OP_MODE_STR_EXCLUSIVE); + break; + case QLA2XXX_OP_MODE_TARGET: + len += scnprintf(buf + len, PAGE_SIZE-len, + QLA2XXX_OP_MODE_STR_TARGET); + break; + case QLA2XXX_OP_MODE_INITIATOR: + len += scnprintf(buf + len, PAGE_SIZE-len, + QLA2XXX_OP_MODE_STR_INITIATOR); + break; + case QLA2XXX_OP_MODE_DUAL: + len += scnprintf(buf + len, PAGE_SIZE-len, + QLA2XXX_OP_MODE_STR_DUAL); + break; + } + len += scnprintf(buf + len, PAGE_SIZE-len, "\n"); + + return len; +} + + +void qla_adj_tgt_exch_pct(scsi_qla_host_t *vha, int op) +{ + /* reserve a few exchange for FW for mgt. */ + switch (op) { + case QLA2XXX_OP_MODE_TARGET: + vha->u_tgt_ex_pct = MAX_TGT_EXCH_PCT; + break; + + case QLA2XXX_OP_MODE_EXCLUSIVE: + if (qla_tgt_mode_enabled(vha) || + qla_dual_mode_enabled(vha)) { + vha->u_tgt_ex_pct = MAX_TGT_EXCH_PCT; + } else + vha->u_tgt_ex_pct = 0; + break; + + case QLA2XXX_OP_MODE_INITIATOR: + /* target mode does not need any exchange reserve. */ + vha->u_tgt_ex_pct = 0; + break; + + case QLA2XXX_OP_MODE_DUAL: + if (vha->u_tgt_ex_pct >= 100) + vha->u_tgt_ex_pct = MAX_TGT_EXCH_PCT;
[PATCH 01/22] qla2xxx: Fix wrong IOCB type assumption.
From: Quinn Tran qlt_reset is call with Immedidate Notification IOCB only. Current code wrongly cast it as ATIO IOCB. Signed-off-by: Quinn Tran Signed-off-by: Himanshu Madhani --- drivers/scsi/qla2xxx/qla_target.c | 6 +- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index bff9689..8a762a6 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -668,11 +668,10 @@ static int qlt_reset(struct scsi_qla_host *vha, void *iocb, int mcmd) { struct qla_hw_data *ha = vha->hw; struct qla_tgt_sess *sess = NULL; - uint32_t unpacked_lun, lun = 0; + uint32_t unpacked_lun = 0; uint16_t loop_id; int res = 0; struct imm_ntfy_from_isp *n = (struct imm_ntfy_from_isp *)iocb; - struct atio_from_isp *a = (struct atio_from_isp *)iocb; unsigned long flags; loop_id = le16_to_cpu(n->u.isp24.nport_handle); @@ -725,9 +724,6 @@ static int qlt_reset(struct scsi_qla_host *vha, void *iocb, int mcmd) "loop_id %d)\n", vha->host_no, sess, sess->port_name, mcmd, loop_id); - lun = a->u.isp24.fcp_cmnd.lun; - unpacked_lun = scsilun_to_int((struct scsi_lun *)&lun); - return qlt_issue_task_mgmt(sess, unpacked_lun, mcmd, iocb, QLA24XX_MGMT_SEND_NACK); } -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 05/22] qla2xxx: Add DebugFS node of irq vector cpuid
From: Quinn Tran > cat /sys/kernel/debug/qla2xxx/*/irq_cpuid qla2xxx_81 IRQ Name Vector CPUID qla2xxx (default) 150 9 qla2xxx (rsp_q)151 9 qla2xxx (atio_q) 152 9 Signed-off-by: Quinn Tran Signed-off-by: Himanshu Madhani --- drivers/scsi/qla2xxx/qla_dbg.c | 2 +- drivers/scsi/qla2xxx/qla_def.h | 1 + drivers/scsi/qla2xxx/qla_dfs.c | 52 +- drivers/scsi/qla2xxx/qla_isr.c | 14 4 files changed, 67 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index 21d9fb7..b2e3167 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c @@ -59,7 +59,7 @@ * | || 0xb13c-0xb140 | * | || 0xb149 | * | MultiQ | 0xc010 | | - * | Misc | 0xd301 | 0xd031-0xd0ff | + * | Misc | 0xd303 | 0xd031-0xd0ff | * | || 0xd101-0xd1fe | * | || 0xd214-0xd2fe | * | Target Mode | 0xe080 || diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 84f2cc3..1e3a3fa 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -3448,6 +3448,7 @@ struct qla_hw_data { struct dentry *dfs_fce; struct dentry *dfs_tgt_counters; struct dentry *dfs_fw_resource_cnt; + struct dentry *dfs_irq_cpuid; dma_addr_t fce_dma; void*fce; diff --git a/drivers/scsi/qla2xxx/qla_dfs.c b/drivers/scsi/qla2xxx/qla_dfs.c index 34272fd..08d7a05 100644 --- a/drivers/scsi/qla2xxx/qla_dfs.c +++ b/drivers/scsi/qla2xxx/qla_dfs.c @@ -13,6 +13,42 @@ static atomic_t qla2x00_dfs_root_count; static int +qla2x00_dfs_irq_cpuid_show(struct seq_file *s, void *unused) +{ + int i; + scsi_qla_host_t *vha = s->private; + struct qla_hw_data *ha = vha->hw; + struct qla_msix_entry *qentry; + + seq_printf(s, "%s\n", vha->host_str); + seq_printf(s, "%20s Vector CPUID\n", "IRQ Name"); + + for (i = 0; i < ha->msix_count; i++) { + qentry = &ha->msix_entries[i]; + if (qentry->have_irq) + seq_printf(s, "%20s %3d %d\n", + qentry->name, qentry->vector, + qentry->cpuid); + } + + return 0; +} + +static int +qla2x00_dfs_irq_cpuid_open(struct inode *inode, struct file *file) +{ + scsi_qla_host_t *vha = inode->i_private; + return single_open(file, qla2x00_dfs_irq_cpuid_show, vha); +} + +static const struct file_operations dfs_irq_cpuid_ops = { + .open = qla2x00_dfs_irq_cpuid_open, + .read = seq_read, + .llseek = seq_lseek, + .release= single_release, +}; + +static int qla2x00_dfs_tgt_sess_show(struct seq_file *s, void *unused) { scsi_qla_host_t *vha = s->private; @@ -293,11 +329,20 @@ ha->tgt.dfs_tgt_sess = debugfs_create_file("tgt_sess", S_IRUSR, ha->dfs_dir, vha, &dfs_tgt_sess_ops); if (!ha->tgt.dfs_tgt_sess) { - ql_log(ql_log_warn, vha, 0x, + ql_log(ql_log_warn, vha, 0xd302, "Unable to create debugFS tgt_sess node.\n"); goto out; } + ha->dfs_irq_cpuid = debugfs_create_file("irq_cpuid", + S_IRUSR, ha->dfs_dir, vha, &dfs_irq_cpuid_ops); + if (!ha->dfs_irq_cpuid) { + ql_log(ql_log_warn, vha, 0xd303, + "Unable to create debugFS irq_cpuid node.\n"); + goto out; + } + + out: return 0; } @@ -307,6 +352,11 @@ { struct qla_hw_data *ha = vha->hw; + if (ha->dfs_irq_cpuid) { + debugfs_remove(ha->dfs_irq_cpuid); + ha->dfs_irq_cpuid = NULL; + } + if (ha->tgt.dfs_tgt_sess) { debugfs_remove(ha->tgt.dfs_tgt_sess); ha->tgt.dfs_tgt_sess = NULL; diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index 98e4904..dec4b37 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -3121,6 +3121,20 @@ struct qla_init_msix_entry { msix_entries[QLA_ATIO_VECTOR].handler, 0, msix_entries[QLA_ATIO_VECTOR].name, rsp); qentry->have_irq = 1; + qentry->irq_notify.notify = qla_irq_affinity_notify; + qentry->irq_notify.release = qla_irq_affinity_release; + + /* Register for CPU affinity notification. */ + irq_set_affinity_notifier(qentry->vector, &qentry->irq
[PATCH 19/22] qla2xxx: Reduce exess wait during chip reset
From: Quinn Tran Per HW recommendation, Soft reset and Risc reset should take 100uS to complete. This change pad the timeout up to 400uS, which should be plenty. Signed-off-by: Quinn Tran Signed-off-by: Himanshu Madhani --- drivers/scsi/qla2xxx/qla_init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index dcb8c49..d8b18a9 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -2112,7 +2112,7 @@ void qla2x00_fcport_event_handler (scsi_qla_host_t *vha, /* Wait for soft-reset to complete. */ RD_REG_DWORD(®->ctrl_status); - for (cnt = 0; cnt < 600; cnt++) { + for (cnt = 0; cnt < 60; cnt++) { barrier(); if ((RD_REG_DWORD(®->ctrl_status) & CSRX_ISP_SOFT_RESET) == 0) @@ -2155,7 +2155,7 @@ void qla2x00_fcport_event_handler (scsi_qla_host_t *vha, RD_REG_DWORD(®->hccr); RD_REG_WORD(®->mailbox0); - for (cnt = 600; RD_REG_WORD(®->mailbox0) != 0 && + for (cnt = 60; RD_REG_WORD(®->mailbox0) != 0 && rval == QLA_SUCCESS; cnt--) { barrier(); if (cnt) -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 14/22] qla2xxx: Add interrupt polling mechanism
From: Quinn Tran This patch adds capability to poll for an interrupt, If hardware does not generate any interrupt for 2 seconds. Signed-off-by: Quinn Tran Signed-off-by: Himanshu Madhani --- drivers/scsi/qla2xxx/qla_def.h| 8 + drivers/scsi/qla2xxx/qla_dfs.c| 75 +++ drivers/scsi/qla2xxx/qla_gbl.h| 1 + drivers/scsi/qla2xxx/qla_isr.c| 22 ++-- drivers/scsi/qla2xxx/qla_os.c | 31 drivers/scsi/qla2xxx/qla_target.c | 6 6 files changed, 141 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 6bf7ff9..09da61f 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -2921,6 +2921,10 @@ struct qla_msix_entry { void *handle; struct irq_affinity_notify irq_notify; int cpuid; + irqreturn_t (*irq_handler)(int, void *); + u32 intr_cnt; + u32 last_intr_cnt; + struct work_struct intr_work; }; #defineWATCH_INTERVAL 1 /* number of seconds */ @@ -3826,6 +3830,10 @@ struct qla_hw_data { struct qlt_hw_data tgt; int allow_cna_fw_dump; + + int irqpoll_interval, irqpoll_cnt; + struct dentry *dfs_irqpoll; +#define MAX_IRQPOLL_INTV 30 }; struct qla_tgt_counters { diff --git a/drivers/scsi/qla2xxx/qla_dfs.c b/drivers/scsi/qla2xxx/qla_dfs.c index f69ff52..18cedf7 100644 --- a/drivers/scsi/qla2xxx/qla_dfs.c +++ b/drivers/scsi/qla2xxx/qla_dfs.c @@ -12,6 +12,68 @@ static struct dentry *qla2x00_dfs_root; static atomic_t qla2x00_dfs_root_count; + +static int +qla_dfs_irqpoll_show(struct seq_file *s, void *unused) +{ + struct scsi_qla_host *vha = s->private; + struct qla_hw_data *ha = vha->hw; + + seq_printf(s, "IRQ poll interval: %d Seconds (max=%d, def=0/off)\n", +ha->irqpoll_interval, MAX_IRQPOLL_INTV); + + return 0; +} + +static ssize_t qla_dfs_irqpoll_write(struct file *file, const char __user *ubuf, + size_t len, loff_t *offp) +{ + struct seq_file *s = file->private_data; + char *buf; + int ret = 0; + int interval = 0; + struct scsi_qla_host *vha = s->private; + struct qla_hw_data *ha = vha->hw; + + buf = memdup_user(ubuf, len); + if (IS_ERR(buf)) + return PTR_ERR(buf); + + if (sscanf(buf, "%d", &interval) != 1) + return -EINVAL; + + if (interval > MAX_IRQPOLL_INTV || interval < 0) + return -ERANGE; + + ha->irqpoll_interval = interval; + + if (ha->irqpoll_interval == 0) + ql_log(ql_log_info, vha, 0x, + "IRQ Poll turned off.\n"); + else + ql_log(ql_log_info, vha, 0x, + "IRQ Poll turned on(%d).\n", ha->irqpoll_interval); + + + kfree(buf); + return (ret) ? ret : len; +} + +static int +qla_dfs_irqpoll_open(struct inode *inode, struct file *file) +{ + struct scsi_qla_host *vha = inode->i_private; + return single_open(file, qla_dfs_irqpoll_show, vha); +} + +static const struct file_operations dfs_irqpoll = { + .open = qla_dfs_irqpoll_open, + .read = seq_read, + .llseek = seq_lseek, + .release= single_release, + .write = qla_dfs_irqpoll_write, +}; + static int qla2x00_dfs_irq_cpuid_show(struct seq_file *s, void *unused) { @@ -357,6 +419,14 @@ goto out; } + ha->dfs_irqpoll = debugfs_create_file("irq_poll_interval", + S_IRUSR, ha->dfs_dir, vha, &dfs_irqpoll); + if (!ha->dfs_irqpoll) { + ql_log(ql_log_warn, vha, 0x, + "Unable to create debugFS irq_poll_interval node.\n"); + goto out; + } + out: return 0; @@ -367,6 +437,11 @@ { struct qla_hw_data *ha = vha->hw; + if (ha->dfs_irqpoll) { + debugfs_remove(ha->dfs_irqpoll); + ha->dfs_irqpoll = NULL; + } + if (ha->dfs_irq_cpuid) { debugfs_remove(ha->dfs_irq_cpuid); ha->dfs_irq_cpuid = NULL; diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 3593a39..944f37a 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -140,6 +140,7 @@ int qla24xx_post_newsess_work(struct scsi_qla_host *, port_id_t *, extern int ql2xexlogins; extern int ql2xexchoffld; extern int ql2xfwholdabts; +extern struct workqueue_struct *qla_wq; extern int qla2x00_loop_reset(scsi_qla_host_t *); extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int); diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index c7f73b1..eee98c9 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -3003,6 +3003,7 @@ void qla24xx_process_respon
[PATCH 11/22] qla2xxx: Refactor session management code.
From: Quinn Tran Current code has 2 structures/codes tracking the same remote port (fc_port & qla_tgt_sess). Merge these structures and code under same fc_port. In target mode, current code does not communicate session state change to initiator side, Merget target and initiator mode sessions into same session. In driver unload path, schedule all session for deletion and wait for deletion complete before allowing driver unload to advance. This patch also refactors unused session deletion in target mode and does cleanup of dead code. Signed-off-by: Quinn Tran Signed-off-by: Himanshu Madhani --- drivers/scsi/qla2xxx/qla_def.h | 3 +- drivers/scsi/qla2xxx/qla_gbl.h | 1 + drivers/scsi/qla2xxx/qla_gs.c | 58 ++- drivers/scsi/qla2xxx/qla_init.c| 159 --- drivers/scsi/qla2xxx/qla_isr.c | 43 +- drivers/scsi/qla2xxx/qla_os.c | 46 +- drivers/scsi/qla2xxx/qla_target.c | 905 ++--- drivers/scsi/qla2xxx/qla_target.h | 4 +- drivers/scsi/qla2xxx/tcm_qla2xxx.c | 17 +- 9 files changed, 762 insertions(+), 474 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index f281f3d..6370aca 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -2162,6 +2162,7 @@ enum fcport_mgt_event { unsigned int keep_nport_handle:1; unsigned int send_els_logo:1; unsigned int login_pause:1; + unsigned int login_succ:1; struct fc_port *conflict; unsigned char logout_completed; @@ -2254,7 +2255,6 @@ struct event_arg { #define FCF_FCP2_DEVICEBIT_2 #define FCF_ASYNC_SENT BIT_3 #define FCF_CONF_COMP_SUPPORTED BIT_4 -#define FCF_DELETE_DEV BIT_5 /* No loop ID flag. */ #define FC_NO_LOOP_ID 0x1000 @@ -4008,6 +4008,7 @@ struct qla_tgt_counters { struct name_list_extended gnl; /* Count of active session/fcport */ int fcport_count; + wait_queue_head_t fcport_waitQ; } scsi_qla_host_t; struct qla27xx_image_status { diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index 94fc7b4..3593a39 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h @@ -844,6 +844,7 @@ void qlt_plogi_ack_link(struct scsi_qla_host *, qlt_plogi_ack_t *, struct fc_port *, qlt_plogi_link_t); void qlt_plogi_ack_unref(struct scsi_qla_host *, qlt_plogi_ack_t *); extern void qlt_schedule_sess_for_deletion(struct fc_port *, bool); +extern void qlt_schedule_sess_for_deletion_lock(struct fc_port *); extern struct fc_port *qlt_find_sess_invalidate_other(scsi_qla_host_t *, uint64_t wwn, port_id_t port_id, uint16_t loop_id, struct fc_port **); void qla24xx_delete_sess_fn(struct work_struct *); diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index d7164da..fa49470 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c @@ -2777,28 +2777,55 @@ void qla24xx_handle_gidpn_event(scsi_qla_host_t *vha, struct event_arg *ea) default: if (atomic_read(&fcport->state) == FCS_ONLINE) break; + + ql_dbg(ql_dbg_disc, vha, 0x, + "%s %d %8phC post gnl\n", + __func__, __LINE__, fcport->port_name); + qla24xx_post_gnl_work(vha, fcport); break; } } else { /* fcport->d_id.b24 != ea->id.b24 */ fcport->d_id.b24 = ea->id.b24; - if (fcport->deleted == QLA_SESS_DELETED) - qlt_schedule_sess_for_deletion(fcport, true); + if (fcport->deleted == QLA_SESS_DELETED) { + ql_dbg(ql_dbg_disc, vha, 0x, + "%s %d %8phC post del sess\n", + __func__, __LINE__, fcport->port_name); + qlt_schedule_sess_for_deletion_lock(fcport); + } } } else { /* ea->sp->gen1 != fcport->rscn_gen */ /* rscn came in while cmd was out */ + ql_dbg(ql_dbg_disc, vha, 0x, + "%s %d %8phC post gidpn\n", + __func__, __LINE__, fcport->port_name); + qla24xx_post_gidpn_work(vha, fcport); } } else { /* ea->rc */ /* cable pulled */ if (ea->sp->gen1 == fcport->rscn_gen) { - if (ea->sp->gen2 == fcport->login
[PATCH 17/22] qla2xxx: Rerfactor use of sp context
From: Joe Carnuccio Signed-off-by: Joe Carnuccio Signed-off-by: Himanshu Madhani --- drivers/scsi/qla2xxx/qla_attr.c | 12 +++ drivers/scsi/qla2xxx/qla_bsg.c| 13 --- drivers/scsi/qla2xxx/qla_def.h| 2 +- drivers/scsi/qla2xxx/qla_gs.c | 14 drivers/scsi/qla2xxx/qla_init.c | 42 +++--- drivers/scsi/qla2xxx/qla_inline.h | 10 +++--- drivers/scsi/qla2xxx/qla_iocb.c | 76 +++ drivers/scsi/qla2xxx/qla_isr.c| 44 +++ drivers/scsi/qla2xxx/qla_mid.c| 12 --- drivers/scsi/qla2xxx/qla_mr.c | 46 +++- drivers/scsi/qla2xxx/qla_os.c | 10 +++--- drivers/scsi/qla2xxx/qla_target.c | 4 +-- 12 files changed, 138 insertions(+), 147 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index d8b77aa..5b53fdd 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c @@ -2498,8 +2498,6 @@ struct device_attribute *qla2x00_host_attrs[] = { "Timer for the VP[%d] has stopped\n", vha->vp_idx); } - BUG_ON(atomic_read(&vha->vref_count)); - qla2x00_free_fcports(vha); mutex_lock(&ha->vport_lock); @@ -2510,10 +2508,12 @@ struct device_attribute *qla2x00_host_attrs[] = { dma_free_coherent(&ha->pdev->dev, vha->gnl.size, vha->gnl.l, vha->gnl.ldma); - if (vha->qpair->vp_idx == vha->vp_idx) { - if (qla2xxx_delete_qpair(vha, vha->qpair) != QLA_SUCCESS) - ql_log(ql_log_warn, vha, 0x7087, - "Queue Pair delete failed.\n"); + if (vha->qpair) { + if (vha->qpair->vp_idx == vha->vp_idx) { + if (qla2xxx_delete_qpair(vha, vha->qpair) != QLA_SUCCESS) + ql_log(ql_log_warn, vha, 0x7087, + "Queue Pair delete failed.\n"); + } } ql_log(ql_log_info, vha, 0x7088, "VP[%d] deleted.\n", id); diff --git a/drivers/scsi/qla2xxx/qla_bsg.c b/drivers/scsi/qla2xxx/qla_bsg.c index cdf0dce..5db25a7 100644 --- a/drivers/scsi/qla2xxx/qla_bsg.c +++ b/drivers/scsi/qla2xxx/qla_bsg.c @@ -16,21 +16,20 @@ qla2x00_bsg_job_done(void *data, void *ptr, int res) { srb_t *sp = (srb_t *)ptr; - struct scsi_qla_host *vha = (scsi_qla_host_t *)data; struct bsg_job *bsg_job = sp->u.bsg_job; struct fc_bsg_reply *bsg_reply = bsg_job->reply; bsg_reply->result = res; bsg_job_done(bsg_job, bsg_reply->result, bsg_reply->reply_payload_rcv_len); - sp->free(vha, sp); + sp->free(sp->vha, sp); } void qla2x00_bsg_sp_free(void *data, void *ptr) { srb_t *sp = (srb_t *)ptr; - struct scsi_qla_host *vha = sp->fcport->vha; + struct scsi_qla_host *vha = sp->vha; struct bsg_job *bsg_job = sp->u.bsg_job; struct fc_bsg_request *bsg_request = bsg_job->request; @@ -62,7 +61,7 @@ sp->type == SRB_FXIOCB_BCMD || sp->type == SRB_ELS_CMD_HST) qla2x00_free_fcport(sp->fcport); - qla2x00_rel_sp(vha, sp); + qla2x00_rel_sp(sp); } int @@ -394,7 +393,7 @@ if (rval != QLA_SUCCESS) { ql_log(ql_log_warn, vha, 0x700e, "qla2x00_start_sp failed = %d\n", rval); - qla2x00_rel_sp(vha, sp); + qla2x00_rel_sp(sp); rval = -EIO; goto done_unmap_sg; } @@ -542,7 +541,7 @@ if (rval != QLA_SUCCESS) { ql_log(ql_log_warn, vha, 0x7017, "qla2x00_start_sp failed=%d.\n", rval); - qla2x00_rel_sp(vha, sp); + qla2x00_rel_sp(sp); rval = -EIO; goto done_free_fcport; } @@ -2578,6 +2577,6 @@ done: spin_unlock_irqrestore(&ha->hardware_lock, flags); - sp->free(vha, sp); + sp->free(sp->vha, sp); return 0; } diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index f9a4528..3464d65 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -433,7 +433,7 @@ struct srb_iocb { typedef struct srb { atomic_t ref_count; struct fc_port *fcport; - void *vha; + struct scsi_qla_host *vha; uint32_t handle; uint16_t flags; uint16_t type; diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index 1e70a58..e36068c 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c @@ -2854,7 +2854,7 @@ void qla2x00_async_gidpn_sp_done(void *v, void *s, int res) qla2x00_fcport_event_handler(vha, &ea); - sp->free(vha, sp); + sp->free(sp->vha, sp); } int qla24xx_async_gidpn(scsi_qla_host_t *vha, fc_port_t *fcport) @@ -2912,7 +2912,7 @@ int qla24xx_async_gidpn(scsi_qla_host_t *vha, fc_po
[PATCH 22/22] qla2xxx: Add check for corrupt ATIO.
From: Quinn Tran corrupt ATIO is defined as length of fcp_header & fcp_cmd payload is less than 0x38. It's the minimum size for a frame to carry 8..16 bytes SCSI CDB. The exchange will be drop or terminated if corrupted Signed-off-by: Quinn Tran Signed-off-by: Himanshu Madhani --- drivers/scsi/qla2xxx/qla_def.h| 3 ++- drivers/scsi/qla2xxx/qla_target.c | 23 --- drivers/scsi/qla2xxx/qla_target.h | 16 +++- 3 files changed, 37 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index de058a1..e1e686f 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -1600,7 +1600,8 @@ struct link_statistics { struct atio { uint8_t entry_type; /* Entry type. */ uint8_t entry_count;/* Entry count. */ - uint8_t data[58]; + uint16_t attr_n_length; + uint8_t data[56]; uint32_tsignature; #define ATIO_PROCESSED 0xDEADDEAD /* Signature */ }; diff --git a/drivers/scsi/qla2xxx/qla_target.c b/drivers/scsi/qla2xxx/qla_target.c index 6f01c66..c7093c79 100644 --- a/drivers/scsi/qla2xxx/qla_target.c +++ b/drivers/scsi/qla2xxx/qla_target.c @@ -6967,12 +6967,29 @@ static void qlt_disable_vha(struct scsi_qla_host *vha) if (!ha->flags.fw_started) return; - while (ha->tgt.atio_ring_ptr->signature != ATIO_PROCESSED) { + while ((ha->tgt.atio_ring_ptr->signature != ATIO_PROCESSED) || + FCPCMD_IS_CORRUPTED(ha->tgt.atio_ring_ptr)) { pkt = (struct atio_from_isp *)ha->tgt.atio_ring_ptr; cnt = pkt->u.raw.entry_count; - qlt_24xx_atio_pkt_all_vps(vha, (struct atio_from_isp *)pkt, - ha_locked); + if (unlikely(FCPCMD_IS_CORRUPTED(ha->tgt.atio_ring_ptr))) { + /* This packet is corrupted. The header + payload +* can not be trusted. There is no point in passing +* it further up. +*/ + ql_log(ql_log_warn, vha, 0x, + "corrupted fcp frame SID[%3phN] " + "OXID[%04x] EXCG[%x] %64phN\n", + pkt->u.isp24.fcp_hdr.s_id, + be16_to_cpu(pkt->u.isp24.fcp_hdr.ox_id), + le32_to_cpu(pkt->u.isp24.exchange_addr), + pkt); + + ADJ_CORRUPTED_ATIO(pkt); + qlt_send_term_exchange(vha, NULL, pkt, ha_locked, 0); + } else + qlt_24xx_atio_pkt_all_vps(vha, (struct atio_from_isp *)pkt, + ha_locked); for (i = 0; i < cnt; i++) { ha->tgt.atio_ring_index++; diff --git a/drivers/scsi/qla2xxx/qla_target.h b/drivers/scsi/qla2xxx/qla_target.h index b57067d..3aff551 100644 --- a/drivers/scsi/qla2xxx/qla_target.h +++ b/drivers/scsi/qla2xxx/qla_target.h @@ -429,7 +429,10 @@ struct atio_from_isp { struct { uint8_t entry_type;/* Entry type. */ uint8_t entry_count; /* Entry count. */ - uint8_t data[58]; + uint16_t attr_n_length; +#define FCP_CMD_LENTH_MASK 0x0fff +#define FCP_CMD_LENTH_MIN 0x38 + uint8_t data[56]; uint32_t signature; #define ATIO_PROCESSED 0xDEADDEAD /* Signature */ } raw; @@ -437,6 +440,17 @@ struct atio_from_isp { } __packed; +#define FCPCMD_IS_CORRUPTED(_a) \ +((_a->entry_type == ATIO_TYPE7) && \ +((le16_to_cpu(_a->attr_n_length) & FCP_CMD_LENTH_MASK) < FCP_CMD_LENTH_MIN)) + +/* adjust corrupted atio so we won't trip over the same entry again. */ +#define ADJ_CORRUPTED_ATIO(_a) \ +{ \ +_a->u.raw.attr_n_length = cpu_to_le16(FCP_CMD_LENTH_MIN); \ +((struct atio_from_isp *)_a)->u.isp24.fcp_cmnd.add_cdb_len = 0; \ +} + #define GET_DL_FR_ATIO(_atio) \ (be32_to_cpu(get_unaligned((uint32_t *) \ &_atio->u.isp24.fcp_cmnd.add_cdb[_atio->u.isp24.fcp_cmnd.add_cdb_len*4]))) -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 21/22] qla2xxx: Improve submission of non critical MB interface.
From: Quinn Tran Move Get ID list, stats and Get Port Databasae mailbox commands out of MB interface which is serialized to IOCB interface to reduce contention. Current driver wait for FW to be in the ready state before processing in coming commands. For loop mode, certain initiator takes longer for login to complete. While other initiators already sends commands. Add processing of Report ID Acquision F2. For Direct connect and target mode, Rida F2 provides the ALPA/Nport ID of the local adapter. Signed-off-by: Quinn Tran Signed-off-by: Himanshu Madhani --- drivers/scsi/qla2xxx/qla_def.h| 34 +++- drivers/scsi/qla2xxx/qla_dfs.c| 85 +- drivers/scsi/qla2xxx/qla_fw.h | 18 +++ drivers/scsi/qla2xxx/qla_gbl.h| 12 +- drivers/scsi/qla2xxx/qla_init.c | 112 ++ drivers/scsi/qla2xxx/qla_isr.c| 22 ++- drivers/scsi/qla2xxx/qla_mbx.c| 315 +++--- drivers/scsi/qla2xxx/qla_os.c | 95 +--- drivers/scsi/qla2xxx/qla_target.c | 53 --- drivers/scsi/qla2xxx/qla_target.h | 5 + 10 files changed, 607 insertions(+), 144 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 404acee..de058a1 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -395,11 +395,15 @@ struct srb_iocb { struct completion comp; } abt; struct ct_arg ctarg; +#define MAX_IOCB_MB_REG 28 +#define SIZEOF_IOCB_MB_REG (MAX_IOCB_MB_REG * sizeof(uint16_t)) struct { - __le16 in_mb[28]; /* fr fw */ - __le16 out_mb[28]; /* to fw */ + __le16 in_mb[MAX_IOCB_MB_REG]; /* fr fw */ + __le16 out_mb[MAX_IOCB_MB_REG]; /* to fw */ void *out, *in; dma_addr_t out_dma, in_dma; + struct completion comp; + int rc; } mbx; struct { struct imm_ntfy_from_isp *ntfy; @@ -2075,7 +2079,7 @@ struct mbx_24xx_entry { /* * Fibre channel port type. */ - typedef enum { +typedef enum { FCT_UNKNOWN, FCT_RSCN, FCT_SWITCH, @@ -3217,6 +3221,8 @@ struct qlt_hw_data { uint8_t tgt_node_name[WWN_SIZE]; struct dentry *dfs_tgt_sess; + struct dentry *dfs_tgt_port_database; + struct list_head q_full_list; uint32_t num_pend_cmds; uint32_t num_qfull_cmds_alloc; @@ -3235,6 +3241,18 @@ struct qlt_hw_data { #define LEAK_EXCHG_THRESH_HOLD_PERCENT 75 /* 75 percent */ +/* */ +enum chip_state { + QLA_CS_ROM = 0, + QLA_FW_OPTIONS, + QLA_INIT_FW, + QLA_CS_FW_RDY, +}; + +#define QLA_EARLY_LINKUP(_ha) \ + ((_ha->flags.n2n_ae || _ha->flags.lip_ae) && \ +_ha->flags.fw_started && !_ha->flags.fw_init_done) + /* * Qlogic host adapter specific data structure. */ @@ -3284,7 +3302,12 @@ struct qla_hw_data { uint32_tfawwpn_enabled:1; uint32_texlogins_enabled:1; uint32_texchoffld_enabled:1; - /* 35 bits */ + + uint32_tlip_ae:1; + uint32_tn2n_ae:1; + uint32_tfw_started:1; + uint32_tfw_init_done:1; + } flags; /* This spinlock is used to protect "io transactions", you must @@ -3866,6 +3889,7 @@ struct qla_tgt_counters { struct list_head vp_fcports;/* list of fcports */ struct list_head work_list; spinlock_t work_lock; + struct work_struct iocb_work; /* Commonly used flags and state information. */ struct Scsi_Host *host; @@ -3885,6 +3909,8 @@ struct qla_tgt_counters { uint32_tfw_tgt_reported:1; uint32_tbbcr_enable:1; uint32_tqpairs_available:1; + + uint32_tiocb_work_sheduled:1; } flags; atomic_tloop_state; diff --git a/drivers/scsi/qla2xxx/qla_dfs.c b/drivers/scsi/qla2xxx/qla_dfs.c index 18cedf7..9fad3a8 100644 --- a/drivers/scsi/qla2xxx/qla_dfs.c +++ b/drivers/scsi/qla2xxx/qla_dfs.c @@ -143,7 +143,6 @@ static ssize_t qla_dfs_irqpoll_write(struct file *file, const char __user *ubuf, return single_open(file, qla2x00_dfs_tgt_sess_show, vha); } - static const struct file_operations dfs_tgt_sess_ops = { .open = qla2x00_dfs_tgt_sess_open, .read = seq_read, @@ -152,6 +151,77 @@ static ssize_t qla_dfs_irqpoll_write(struct file *file, const char __user *ubuf, }; static int +qla2x00_dfs_tgt_port_database_show(struct seq_file *s, void *unused) +{ + scsi_qla_host_t *vha = s->private; + struct qla_hw_data *ha = vha->hw; + struct gid_list_info *gid_list; + dma_addr_t gid_list_dma; + fc_port_t f
[PATCH 20/22] qla2xxx: Allow relogin to go through if remote login did not finish
From: Quinn Tran Signed-off-by: Quinn Tran Signed-off-by: Himanshu Madhani --- drivers/scsi/qla2xxx/qla_def.h| 2 ++ drivers/scsi/qla2xxx/qla_init.c | 14 -- drivers/scsi/qla2xxx/qla_isr.c| 25 +++-- drivers/scsi/qla2xxx/qla_os.c | 2 +- drivers/scsi/qla2xxx/qla_target.c | 2 ++ 5 files changed, 36 insertions(+), 9 deletions(-) diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index 3464d65..404acee 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h @@ -2216,6 +2216,8 @@ enum rscn_addr_format { struct ct_sns_desc ct_desc; enum discovery_state disc_state; enum login_state fw_login_state; + unsigned long plogi_nack_done_jiff; + u32 login_gen, last_login_gen; u32 rscn_gen, last_rscn_gen; u32 chip_reset; diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index d8b18a9..549a7c6 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -895,10 +895,15 @@ int qla24xx_fcport_handle_login(struct scsi_qla_host *vha, fc_port_t *fcport) fcport->login_retry--; if ((fcport->fw_login_state == DSC_LS_PLOGI_PEND) || - (fcport->fw_login_state == DSC_LS_PLOGI_COMP) || (fcport->fw_login_state == DSC_LS_PRLI_PEND)) return 0; + if (fcport->fw_login_state == DSC_LS_PLOGI_COMP) { + unsigned long t = fcport->plogi_nack_done_jiff + HZ; + if (time_before_eq(jiffies, t)) + return 0; + } + if (vha->host->active_mode == MODE_TARGET) /* for pure Target Mode. Login will not be initiated */ return 0; @@ -1060,10 +1065,15 @@ void qla24xx_handle_relogin_event(scsi_qla_host_t *vha, fcport->flags); if ((fcport->fw_login_state == DSC_LS_PLOGI_PEND) || - (fcport->fw_login_state == DSC_LS_PLOGI_COMP) || (fcport->fw_login_state == DSC_LS_PRLI_PEND)) return; + if (fcport->fw_login_state == DSC_LS_PLOGI_COMP) { + unsigned long t = fcport->plogi_nack_done_jiff + HZ; + if (time_before_eq(jiffies, t)) + return; + } + if (fcport->flags & FCF_ASYNC_SENT) { fcport->login_retry++; set_bit(RELOGIN_NEEDED, &vha->dpc_flags); diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index c81ada0..c02033b 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c @@ -1625,9 +1625,9 @@ static void qla_irq_affinity_notify(struct irq_affinity_notify *, QLA_LOGIO_LOGIN_RETRIED : 0; if (logio->entry_status) { ql_log(ql_log_warn, fcport->vha, 0x5034, - "Async-%s error entry - hdl=%x" + "Async-%s error entry - %8phC hdl=%x" "portid=%02x%02x%02x entry-status=%x.\n", - type, sp->handle, fcport->d_id.b.domain, + type, fcport->port_name, sp->handle, fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa, logio->entry_status); ql_dump_buffer(ql_dbg_async + ql_dbg_buffer, vha, 0x504d, @@ -1638,8 +1638,9 @@ static void qla_irq_affinity_notify(struct irq_affinity_notify *, if (le16_to_cpu(logio->comp_status) == CS_COMPLETE) { ql_dbg(ql_dbg_async, fcport->vha, 0x5036, - "Async-%s complete - hdl=%x portid=%02x%02x%02x " - "iop0=%x.\n", type, sp->handle, fcport->d_id.b.domain, + "Async-%s complete - %8phC hdl=%x portid=%02x%02x%02x " + "iop0=%x.\n", type, fcport->port_name, sp->handle, + fcport->d_id.b.domain, fcport->d_id.b.area, fcport->d_id.b.al_pa, le32_to_cpu(logio->io_parameter[0])); @@ -1679,6 +1680,17 @@ static void qla_irq_affinity_notify(struct irq_affinity_notify *, case LSC_SCODE_NPORT_USED: data[0] = MBS_LOOP_ID_USED; break; + case LSC_SCODE_CMD_FAILED: + if (iop[1] == 0x0606) { + /* PLOGI/PRLI Completed. We must have Recv PLOGI/PRLI, +* Target side acked. +*/ + data[0] = MBS_COMMAND_COMPLETE; + goto logio_done; + break; + } + data[0] = MBS_COMMAND_ERROR; + break; case LSC_SCODE_NOXCB: vha->hw->exch_starvation++; if (vha->hw->exch_starvation > 5) { @@ -1700,8 +1712,9 @@ static void qla_irq_affinity_notify(struct irq_affinity_notify *, } ql_dbg(ql_dbg_async, fcport->vha, 0x5037, - "Async-%s failed - hdl=%x portid=%02x%02x%0
RE: [PATCH 2/4] hpsa: add generate controller NMI on lockup
> -Original Message- > From: linux-scsi-ow...@vger.kernel.org [mailto:linux-scsi- > ow...@vger.kernel.org] On Behalf Of Don Brace > Sent: Friday, November 11, 2016 10:09 AM > To: Hannes Reinecke; j...@linux.vnet.ibm.com; John Hall; Kevin Barnett; > Mahesh Rajashekhara; h...@infradead.org; Scott Teel; Viswas G; Justin > Lindley; Scott Benesh; elli...@hpe.com; posw...@suse.com > Cc: linux-scsi@vger.kernel.org > Subject: RE: [PATCH 2/4] hpsa: add generate controller NMI on lockup > > EXTERNAL EMAIL > > > > -Original Message- > > From: Hannes Reinecke [mailto:h...@suse.de] > > Sent: Thursday, October 27, 2016 4:03 AM > > To: Don Brace; j...@linux.vnet.ibm.com; John Hall; Kevin Barnett; Mahesh > > Rajashekhara; h...@infradead.org; Scott Teel; Viswas G; Justin Lindley; > Scott > > Benesh; elli...@hpe.com; posw...@suse.com > > Cc: linux-scsi@vger.kernel.org > > Subject: Re: [PATCH 2/4] hpsa: add generate controller NMI on lockup > > > > EXTERNAL EMAIL > > > > > > On 10/27/2016 12:21 AM, Don Brace wrote: > > > Tell the controller to NMI when the controller deadlocks. > > > > > > Reviewed-by: Scott Benesh > > > Reviewed-by: Scott Teel > > > Reviewed-by: Kevin Barnett > > > Signed-off-by: Don Brace > > > --- > > > drivers/scsi/hpsa.c |6 ++ > > > drivers/scsi/hpsa_cmd.h |1 + > > > 2 files changed, 7 insertions(+) > > > > > > diff --git a/drivers/scsi/hpsa.c b/drivers/scsi/hpsa.c > > > index 798fb20..9fb739c 100644 > > > --- a/drivers/scsi/hpsa.c > > > +++ b/drivers/scsi/hpsa.c > > > @@ -8451,6 +8451,12 @@ static void controller_lockup_detected(struct > > ctlr_info *h) > > > "lockup detected after %d but scratchpad register > > > is zero\n", > > > h->heartbeat_sample_interval / HZ); > > > lockup_detected = 0x; > > > + } else if (lockup_detected == 0x) { > > > + /* > > > + * Ring controller NMI doorbell > > > + */ > > > + dev_warn(&h->pdev->dev, "Telling controller to do an > > > NMI\n"); > > > + writel(DOORBELL_GENERATE_NMI, h->vaddr + SA5_DOORBELL); > > > } > > > set_lockup_detected_for_all_cpus(h, lockup_detected); > > > spin_unlock_irqrestore(&h->lock, flags); > > > diff --git a/drivers/scsi/hpsa_cmd.h b/drivers/scsi/hpsa_cmd.h > > > index a584cdf..d186f80 100644 > > > --- a/drivers/scsi/hpsa_cmd.h > > > +++ b/drivers/scsi/hpsa_cmd.h > > > @@ -142,6 +142,7 @@ > > > #define DOORBELL_CTLR_RESET 0x0004l > > > #define DOORBELL_CTLR_RESET2 0x0020l > > > #define DOORBELL_CLEAR_EVENTS0x0040l > > > +#define DOORBELL_GENERATE_NMI0x0080l > > > > > > #define CFGTBL_Trans_Simple 0x0002l > > > #define CFGTBL_Trans_Performant 0x0004l > > > > > Care to elaborate a bit more here? > > 'Generating NMI' tends to ring some alarm bells, so I'd rather know > > where the NMI is actually generated, and if is could reflect back to the > > system ... > > > > Cheers, > > > > Hannes > > -- > > Dr. Hannes ReineckeTeamlead Storage & Networking > > h...@suse.de +49 911 74053 688 > > SUSE LINUX GmbH, Maxfeldstr. 5, 90409 Nürnberg > > GF: F. Imendörffer, J. Smithard, J. Guild, D. Upmanyu, G. Norton > > HRB 21284 (AG Nürnberg) > > > There are some rare cases where we get this lockup code and we > need to tell the controller to do its own NMI. This NMI is only done > on the controller and does not tell the OS to perform an NMI. > > Thanks, > Don Brace Wondering what has happened to this patch? Thanks, Don Brace ESC - Smart Storage Microsemi Corporation
[PATCH V4 00/11] megaraid_sas: Updates for scsi-next
Sasikumar Chandrasekaran (11): megaraid_sas: Add new pci device Ids for SAS3.5 Generic Megaraid Controllers megaraid_sas: 128 MSIX Support megaraid_sas: EEDP Escape Mode Support for SAS3.5 Generic Megaraid Controllers megaraid_sas: SAS3.5 Generic Megaraid Controllers Stream Detection and IO Coalescing megaraid_sas: SAS3.5 Generic Megaraid Controllers Fast Path for RAID 1/10 Writes megaraid_sas: Dynamic Raid Map Changes for SAS3.5 Generic Megaraid Controllers megaraid_sas: Add the Support for SAS3.5 Generic Megaraid Controllers Capabilities megaraid_sas: Enable or Disable Fast path based on the PCI Threshold Bandwidth megaraid_sas: ldio_outstanding variable is not decremented in completion path megaraid_sas: Implement the PD Map support for SAS3.5 Generic Megaraid Controllers megaraid_sas: driver version upgrade drivers/scsi/megaraid/megaraid_sas.h| 139 +++-- drivers/scsi/megaraid/megaraid_sas_base.c | 240 +++-- drivers/scsi/megaraid/megaraid_sas_fp.c | 343 +++-- drivers/scsi/megaraid/megaraid_sas_fusion.c | 756 +++- drivers/scsi/megaraid/megaraid_sas_fusion.h | 364 -- 5 files changed, 1564 insertions(+), 278 deletions(-) -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH V4 03/11] megaraid_sas: EEDP Escape Mode Support for SAS3.5 Generic Megaraid Controllers
An UNMAP command on a PI formatted device will leave the Logical Block Application Tag and Logical Block Reference Tag as all F's (for those LBAs that are unmapped). To avoid IO errors if those LBAs are subsequently read before they are written with valid tag fields, the MPI SCSI IO requests need to set the EEDPFlags element EEDP Escape Mode field, Bits [7:6] appropriately. A value of 2 should be set to disable all PI checks if the Logical Block Application Tag is 0x for PI types 1 and 2. A value of 3 should be set to disable all PI checks if the Logical Block Application Tag is 0x and the Logical Block Reference Tag is 0x for PI type 3. This patch is depending on patch 2 Signed-off-by: Sasikumar Chandrasekaran --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 1 + drivers/scsi/megaraid/megaraid_sas_fusion.h | 2 ++ 2 files changed, 3 insertions(+) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 413e2030..fe69c4a 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -1589,6 +1589,7 @@ static int megasas_create_sg_sense_fusion(struct megasas_instance *instance) MPI2_SCSIIO_EEDPFLAGS_CHECK_REFTAG | MPI2_SCSIIO_EEDPFLAGS_CHECK_REMOVE_OP | MPI2_SCSIIO_EEDPFLAGS_CHECK_APPTAG | + MPI25_SCSIIO_EEDPFLAGS_DO_NOT_DISABLE_MODE | MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD); } else { io_request->EEDPFlags = cpu_to_le16( diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.h b/drivers/scsi/megaraid/megaraid_sas_fusion.h index e3bee04..9d22ade 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.h +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.h @@ -175,6 +175,8 @@ enum REGION_TYPE { #define MPI2_SCSIIO_EEDPFLAGS_CHECK_APPTAG (0x0200) #define MPI2_SCSIIO_EEDPFLAGS_CHECK_GUARD (0x0100) #define MPI2_SCSIIO_EEDPFLAGS_INSERT_OP (0x0004) +/* EEDP escape mode */ +#define MPI25_SCSIIO_EEDPFLAGS_DO_NOT_DISABLE_MODE (0x0040) #define MPI2_FUNCTION_SCSI_IO_REQUEST (0x00) /* SCSI IO */ #define MPI2_FUNCTION_SCSI_TASK_MGMT(0x01) #define MPI2_REQ_DESCRIPT_FLAGS_HIGH_PRIORITY (0x03) -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH V4 09/11] megaraid_sas: ldio_outstanding variable is not decremented in completion path
ldio outstanding variable needs to be decremented in io completion path for iMR dual queue depth This patch is depending on patch 8 Signed-off-by: Sasikumar Chandrasekaran --- drivers/scsi/megaraid/megaraid_sas_fusion.c | 9 +++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 5992153..3598590 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -2584,7 +2584,6 @@ void megasas_prepare_secondRaid1_IO(struct megasas_instance *instance, if (atomic_inc_return(&instance->fw_outstanding) > instance->host->can_queue) { - dev_err(&instance->pdev->dev, "Throttle IOs beyond Controller queue depth\n"); atomic_dec(&instance->fw_outstanding); return SCSI_MLQUEUE_HOST_BUSY; } @@ -2818,6 +2817,10 @@ void megasas_prepare_secondRaid1_IO(struct megasas_instance *instance, = 0; scsi_io_req->RaidContext.raid_context.ex_status = 0; + if (instance->ldio_threshold + && megasas_cmd_type(scmd_local) + == READ_WRITE_LDIO) + atomic_dec(&instance->ldio_outstanding); megasas_return_cmd_fusion(instance, cmd_fusion); scsi_dma_unmap(scmd_local); scmd_local->scsi_done(scmd_local); @@ -3966,7 +3969,9 @@ int megasas_reset_fusion(struct Scsi_Host *shost, int reason) scmd_local->result = megasas_check_mpio_paths(instance, scmd_local); - if (megasas_cmd_type(scmd_local) == READ_WRITE_LDIO) + if (instance->ldio_threshold && + megasas_cmd_type(scmd_local) + == READ_WRITE_LDIO) atomic_dec(&instance->ldio_outstanding); megasas_return_cmd_fusion(instance, cmd_fusion); scsi_dma_unmap(scmd_local); -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH V4 06/11] megaraid_sas: Dynamic Raid Map Changes for SAS3.5 Generic Megaraid Controllers
SAS3.5 Generic Megaraid Controllers FW will support new dynamic RaidMap to have different sizes for different number of supported VDs. This patch is depending on patch 5 Signed-off-by: Sasikumar Chandrasekaran --- drivers/scsi/megaraid/megaraid_sas.h| 7 + drivers/scsi/megaraid/megaraid_sas_base.c | 61 -- drivers/scsi/megaraid/megaraid_sas_fp.c | 303 drivers/scsi/megaraid/megaraid_sas_fusion.c | 223 drivers/scsi/megaraid/megaraid_sas_fusion.h | 240 ++ 5 files changed, 699 insertions(+), 135 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index f4d6a94..3e087ab 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -1434,6 +1434,12 @@ enum FW_BOOT_CONTEXT { #define MR_MAX_REPLY_QUEUES_EXT_OFFSET_SHIFT14 #define MR_MAX_MSIX_REG_ARRAY 16 #define MR_RDPQ_MODE_OFFSET0X0080 + +#define MR_MAX_RAID_MAP_SIZE_OFFSET_SHIFT 16 +#define MR_MAX_RAID_MAP_SIZE_MASK 0x1FF +#define MR_MIN_MAP_SIZE0x1 +/* 64k */ + #define MR_CAN_HANDLE_SYNC_CACHE_OFFSET0X0100 /* @@ -2152,6 +2158,7 @@ struct megasas_instance { bool fw_sync_cache_support; bool is_ventura; bool msix_combined; + u16 max_raid_mapsize; }; struct MR_LD_VF_MAP { u32 size; diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index c52f7be..3f06b57 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -4424,8 +4424,7 @@ int megasas_alloc_cmds(struct megasas_instance *instance) static void megasas_update_ext_vd_details(struct megasas_instance *instance) { struct fusion_context *fusion; - u32 old_map_sz; - u32 new_map_sz; + u32 ventura_map_sz = 0; fusion = instance->ctrl_context; /* For MFI based controllers return dummy success */ @@ -4455,21 +4454,39 @@ static void megasas_update_ext_vd_details(struct megasas_instance *instance) instance->supportmax256vd ? "Extended VD(240 VD)firmware" : "Legacy(64 VD) firmware"); - old_map_sz = sizeof(struct MR_FW_RAID_MAP) + - (sizeof(struct MR_LD_SPAN_MAP) * - (instance->fw_supported_vd_count - 1)); - new_map_sz = sizeof(struct MR_FW_RAID_MAP_EXT); - fusion->drv_map_sz = sizeof(struct MR_DRV_RAID_MAP) + - (sizeof(struct MR_LD_SPAN_MAP) * - (instance->drv_supported_vd_count - 1)); - - fusion->max_map_sz = max(old_map_sz, new_map_sz); + if (instance->max_raid_mapsize) { + ventura_map_sz = instance->max_raid_mapsize * + MR_MIN_MAP_SIZE; /* 64k */ + fusion->current_map_sz = ventura_map_sz; + fusion->max_map_sz = ventura_map_sz; + } else { + fusion->old_map_sz = sizeof(struct MR_FW_RAID_MAP) + + (sizeof(struct MR_LD_SPAN_MAP) * + (instance->fw_supported_vd_count - 1)); + fusion->new_map_sz = sizeof(struct MR_FW_RAID_MAP_EXT); + fusion->max_map_sz = + max(fusion->old_map_sz, fusion->new_map_sz); - if (instance->supportmax256vd) - fusion->current_map_sz = new_map_sz; - else - fusion->current_map_sz = old_map_sz; + if (instance->supportmax256vd) + fusion->current_map_sz = fusion->new_map_sz; + else + fusion->current_map_sz = fusion->old_map_sz; + } + /* irrespective of FW raid maps, driver raid map is constant */ + fusion->drv_map_sz = sizeof(struct MR_DRV_RAID_MAP_ALL); +#if VD_EXT_DEBUG + dev_info(&instance->pdev->dev, "instance->max_raid_mapsize 0x%x \n ", + instance->max_raid_mapsize); + dev_info(&instance->pdev->dev, + "new_map_sz = 0x%x, old_map_sz = 0x%x, " + "ventura_map_sz = 0x%x, current_map_sz = 0x%x " + "fusion->drv_map_sz =0x%x, size of driver raid map 0x%lx\n", + fusion->new_map_sz, fusion->old_map_sz, + ventura_map_sz, fusion->current_map_sz, + fusion->drv_map_sz, + sizeof(struct MR_DRV_RAID_MAP_ALL)); +#endif } /** @@ -5010,7 +5027,7 @@ static int megasas_init_fw(struct megasas_instance *instance) { u32 max_sectors_1; u32 max_sectors_2; - u32 tmp_sectors, msix_enable, scratch_pad_2; + u32 tmp_sectors, msix_enable, scratch_pad_2, scratch_pad_3; resource_size_t base_addr; struct megasas_register_set __iomem *reg_set; struct megasas_ctrl_info *ctrl_inf
[PATCH V4 10/11] megaraid_sas: Implement the PD Map support for SAS3.5 Generic Megaraid Controllers
Update Linux driver to use new pdTargetId field for JBOD target ID This patch is depending on patch 9 Signed-off-by: Sasikumar Chandrasekaran --- drivers/scsi/megaraid/megaraid_sas.h| 105 +--- drivers/scsi/megaraid/megaraid_sas_base.c | 3 + drivers/scsi/megaraid/megaraid_sas_fusion.c | 1 + drivers/scsi/megaraid/megaraid_sas_fusion.h | 3 +- 4 files changed, 84 insertions(+), 28 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index eb5be2b..7334e07 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -1317,7 +1317,55 @@ struct megasas_ctrl_info { #endif } adapterOperations3; - u8 pad[0x800-0x7EC]; + struct { +#if defined(__BIG_ENDIAN_BITFIELD) + u8 reserved:7; + /* Indicates whether the CPLD image is part of + * the package and stored in flash + */ + u8 cpld_in_flash:1; +#else + u8 cpld_in_flash:1; + u8 reserved:7; +#endif + u8 reserved1[3]; + /* Null terminated string. Has the version + * information if cpld_in_flash = FALSE + */ + u8 userCodeDefinition[12]; + } cpld; /* Valid only if upgradableCPLD is TRUE */ + + struct { + #if defined(__BIG_ENDIAN_BITFIELD) + u16 reserved:8; + u16 fw_swaps_bbu_vpd_info:1; + u16 support_pd_map_target_id:1; + u16 support_ses_ctrl_in_multipathcfg:1; + u16 image_upload_supported:1; + u16 support_encrypted_mfc:1; + u16 supported_enc_algo:1; + u16 support_ibutton_less:1; + u16 ctrl_info_ext_supported:1; + #else + + u16 ctrl_info_ext_supported:1; + u16 support_ibutton_less:1; + u16 supported_enc_algo:1; + u16 support_encrypted_mfc:1; + u16 image_upload_supported:1; + /* FW supports LUN based association and target port based */ + u16 support_ses_ctrl_in_multipathcfg:1; + /* association for the SES device connected in multipath mode */ +/* FW defines Jbod target Id within MR_PD_CFG_SEQ */ + u16 support_pd_map_target_id:1; + /* FW swaps relevant fields in MR_BBU_VPD_INFO_FIXED to + * provide the data in little endian order + */ + u16 fw_swaps_bbu_vpd_info:1; + u16 reserved:8; + #endif + } adapter_operations4; + u8 pad[0x800-0x7FE]; /* 0x7FE pad to 2K for expansion */ } __packed; /* @@ -1557,33 +1605,35 @@ struct megasas_header { typedef union _MFI_CAPABILITIES { struct { #if defined(__BIG_ENDIAN_BITFIELD) - u32 reserved:20; - u32 support_qd_throttling:1; - u32 support_fp_rlbypass:1; - u32 support_vfid_in_ioframe:1; - u32 support_ext_io_size:1; - u32 support_ext_queue_depth:1; - u32 security_protocol_cmds_fw:1; - u32 support_core_affinity:1; - u32 support_ndrive_r1_lb:1; - u32 support_max_255lds:1; - u32 support_fastpath_wb:1; - u32 support_additional_msix:1; - u32 support_fp_remote_lun:1; + u32 reserved:19; + u32 support_pd_map_target_id:1; + u32 support_qd_throttling:1; + u32 support_fp_rlbypass:1; + u32 support_vfid_in_ioframe:1; + u32 support_ext_io_size:1; + u32 support_ext_queue_depth:1; + u32 security_protocol_cmds_fw:1; + u32 support_core_affinity:1; + u32 support_ndrive_r1_lb:1; + u32 support_max_255lds:1; + u32 support_fastpath_wb:1; + u32 support_additional_msix:1; + u32 support_fp_remote_lun:1; #else - u32 support_fp_remote_lun:1; - u32 support_additional_msix:1; - u32 support_fastpath_wb:1; - u32 support_max_255lds:1; - u32 support_ndrive_r1_lb:1; - u32 support_core_affinity:1; - u32 security_protocol_cmds_fw:1; - u32 support_ext_queue_depth:1; - u32 support_ext_io_size:1; - u32 support_vfid_in_ioframe:1; - u32 support_fp_rlbypass:1; - u32 support_qd_throttling:1; - u32 reserved:20; + u32 support_fp_remote_lun:1; + u32 support_additional_msix:1; + u32 support_fastpath_wb:1; + u32 support_max_255lds:1; + u32 support_ndrive_r1_lb:1; + u32 support_core_affinity:1; + u32 security_protocol_cmds_fw:1; + u32 su
[PATCH V4 01/11] megaraid_sas: Add new pci device Ids for SAS3.5 Generic Megaraid Controllers
This patch contains new pci device ids for SAS3.5 Generic Megaraid Controllers V4: Removed the not supported PCI Device Ids Signed-off-by: Sasikumar Chandrasekaran --- drivers/scsi/megaraid/megaraid_sas.h| 8 +++- drivers/scsi/megaraid/megaraid_sas_base.c | 14 +- drivers/scsi/megaraid/megaraid_sas_fusion.c | 30 ++--- 3 files changed, 43 insertions(+), 9 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 0d2625b..72e16c2 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -56,6 +56,11 @@ #define PCI_DEVICE_ID_LSI_INTRUDER_24 0x00cf #define PCI_DEVICE_ID_LSI_CUTLASS_52 0x0052 #define PCI_DEVICE_ID_LSI_CUTLASS_53 0x0053 +#define PCI_DEVICE_ID_LSI_VENTURA 0x0014 +#define PCI_DEVICE_ID_LSI_HARPOON 0x0016 +#define PCI_DEVICE_ID_LSI_TOMCAT 0x0017 +#define PCI_DEVICE_ID_LSI_VENTURA_4PORT0x001B +#define PCI_DEVICE_ID_LSI_CRUSADER_4PORT 0x001C /* * Intel HBA SSDIDs @@ -1478,7 +1483,7 @@ struct megasas_register_set { u32 inbound_high_queue_port ; /*00C4h*/ - u32 reserved_5; /*00C8h*/ + u32 inbound_single_queue_port; /*00C8h*/ u32 res_6[11]; /*CCh*/ u32 host_diag; u32 seq_offset; @@ -2143,6 +2148,7 @@ struct megasas_instance { u8 is_rdpq; bool dev_handle; bool fw_sync_cache_support; + bool is_ventura; }; struct MR_LD_VF_MAP { u32 size; diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 5462676..efccf98 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -155,6 +155,12 @@ static int megasas_register_aen(struct megasas_instance *instance, /* Intruder 24 port*/ {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_CUTLASS_52)}, {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_CUTLASS_53)}, + /* VENTURA */ + {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_VENTURA)}, + {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_HARPOON)}, + {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_TOMCAT)}, + {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_VENTURA_4PORT)}, + {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_CRUSADER_4PORT)}, {} }; @@ -5723,6 +5729,12 @@ static int megasas_probe_one(struct pci_dev *pdev, instance->pdev = pdev; switch (instance->pdev->device) { + case PCI_DEVICE_ID_LSI_VENTURA: + case PCI_DEVICE_ID_LSI_HARPOON: + case PCI_DEVICE_ID_LSI_TOMCAT: + case PCI_DEVICE_ID_LSI_VENTURA_4PORT: + case PCI_DEVICE_ID_LSI_CRUSADER_4PORT: +instance->is_ventura = true; case PCI_DEVICE_ID_LSI_FUSION: case PCI_DEVICE_ID_LSI_PLASMA: case PCI_DEVICE_ID_LSI_INVADER: @@ -5747,7 +5759,7 @@ static int megasas_probe_one(struct pci_dev *pdev, if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) || (instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA)) fusion->adapter_type = THUNDERBOLT_SERIES; - else + else if (!instance->is_ventura) fusion->adapter_type = INVADER_SERIES; } break; diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 24778ba..8d7a397 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -189,15 +189,29 @@ inline void megasas_return_cmd_fusion(struct megasas_instance *instance, */ static void megasas_fire_cmd_fusion(struct megasas_instance *instance, - union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc) + union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc, bool is_32bit) { + struct megasas_register_set __iomem *regs = instance->reg_set; + unsigned long flags; + + if (is_32bit) + writel(le32_to_cpu(req_desc->u.low), + &(regs)->inbound_single_queue_port); + else if (instance->is_ventura) { + spin_lock_irqsave(&instance->hba_lock, flags); + writel(le32_to_cpu(req_desc->u.low), + &(regs)->inbound_low_queue_port); + writel(le32_to_cpu(req_desc->u.high), + &(regs)->inbound_high_queue_port); + mmiowb(); + spin_unlock_irqrestore(&instance->hba_lock, flags); + } else { #if defined(writeq) && defined(CONFIG_64BIT) u64 req_data = (((u64)le32_to_cpu(req_desc->u.high) << 32) | le32_to_cpu(req_desc->u.low)); writeq(req_data, &instance->r
[PATCH V4 11/11] megaraid_sas: driver version upgrade
Upgrade driver version. This patch is depending on patch 10 Signed-off-by: Sasikumar Chandrasekaran --- drivers/scsi/megaraid/megaraid_sas.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 7334e07..310555a 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -35,8 +35,8 @@ /* * MegaRAID SAS Driver meta data */ -#define MEGASAS_VERSION"06.812.07.00-rc1" -#define MEGASAS_RELDATE"August 22, 2016" +#define MEGASAS_VERSION"07.700.00.00-rc1" +#define MEGASAS_RELDATE"November 29, 2016" /* * Device IDs -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH V4 07/11] megaraid_sas: Add the Support for SAS3.5 Generic Megaraid Controllers Capabilities
The Megaraid driver has to support the SAS3.5 Generic Megaraid Controllers Firmware functionality. This patch is depending on patch 6 Signed-off-by: Sasikumar Chandrasekaran --- drivers/scsi/megaraid/megaraid_sas_base.c | 53 ++--- drivers/scsi/megaraid/megaraid_sas_fusion.c | 19 ++- drivers/scsi/megaraid/megaraid_sas_fusion.h | 1 + 3 files changed, 37 insertions(+), 36 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 3f06b57..8aafb59 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -5057,34 +5057,29 @@ static int megasas_init_fw(struct megasas_instance *instance) reg_set = instance->reg_set; - switch (instance->pdev->device) { - case PCI_DEVICE_ID_LSI_FUSION: - case PCI_DEVICE_ID_LSI_PLASMA: - case PCI_DEVICE_ID_LSI_INVADER: - case PCI_DEVICE_ID_LSI_FURY: - case PCI_DEVICE_ID_LSI_INTRUDER: - case PCI_DEVICE_ID_LSI_INTRUDER_24: - case PCI_DEVICE_ID_LSI_CUTLASS_52: - case PCI_DEVICE_ID_LSI_CUTLASS_53: + if (fusion) instance->instancet = &megasas_instance_template_fusion; - break; - case PCI_DEVICE_ID_LSI_SAS1078R: - case PCI_DEVICE_ID_LSI_SAS1078DE: - instance->instancet = &megasas_instance_template_ppc; - break; - case PCI_DEVICE_ID_LSI_SAS1078GEN2: - case PCI_DEVICE_ID_LSI_SAS0079GEN2: - instance->instancet = &megasas_instance_template_gen2; - break; - case PCI_DEVICE_ID_LSI_SAS0073SKINNY: - case PCI_DEVICE_ID_LSI_SAS0071SKINNY: - instance->instancet = &megasas_instance_template_skinny; - break; - case PCI_DEVICE_ID_LSI_SAS1064R: - case PCI_DEVICE_ID_DELL_PERC5: - default: - instance->instancet = &megasas_instance_template_xscale; - break; + else { + switch (instance->pdev->device) { + case PCI_DEVICE_ID_LSI_SAS1078R: + case PCI_DEVICE_ID_LSI_SAS1078DE: + instance->instancet = &megasas_instance_template_ppc; + break; + case PCI_DEVICE_ID_LSI_SAS1078GEN2: + case PCI_DEVICE_ID_LSI_SAS0079GEN2: + instance->instancet = &megasas_instance_template_gen2; + break; + case PCI_DEVICE_ID_LSI_SAS0073SKINNY: + case PCI_DEVICE_ID_LSI_SAS0071SKINNY: + instance->instancet = &megasas_instance_template_skinny; + break; + case PCI_DEVICE_ID_LSI_SAS1064R: + case PCI_DEVICE_ID_DELL_PERC5: + default: + instance->instancet = &megasas_instance_template_xscale; + instance->pd_list_not_supported = 1; + break; + } } if (megasas_transition_to_ready(instance, 0)) { @@ -5828,7 +5823,9 @@ static int megasas_probe_one(struct pci_dev *pdev, if ((instance->pdev->device == PCI_DEVICE_ID_LSI_FUSION) || (instance->pdev->device == PCI_DEVICE_ID_LSI_PLASMA)) fusion->adapter_type = THUNDERBOLT_SERIES; - else if (!instance->is_ventura) + else if (instance->is_ventura) + fusion->adapter_type = VENTURA_SERIES; + else fusion->adapter_type = INVADER_SERIES; } break; diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 58f86aa..f968a23 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -244,7 +244,10 @@ inline void megasas_return_cmd_fusion(struct megasas_instance *instance, reg_set = instance->reg_set; - cur_max_fw_cmds = readl(&instance->reg_set->outbound_scratch_pad_3) & 0x00; + /* ventura FW does not fill outbound_scratch_pad_3 with queue depth */ + if (!instance->is_ventura) + cur_max_fw_cmds = + readl(&instance->reg_set->outbound_scratch_pad_3) & 0x00; if (dual_qdepth_disable || !cur_max_fw_cmds) cur_max_fw_cmds = instance->instancet->read_fw_status_reg(reg_set) & 0x00; @@ -843,7 +846,7 @@ static int megasas_create_sg_sense_fusion(struct megasas_instance *instance) drv_ops = (MFI_CAPABILITIES *) &(init_frame->driver_operations); /* driver support Extended MSIX */ - if (fusion->adapter_type == INVADER_SERIES) + if (fusion->adapter_type >= INVADER_SERIES) drv_ops->mfi_capabilities.support_additional_msix = 1; /* driver supports HA / Remote LUN over Fast Path interface */ drv_ops->mfi_capabilities.support_fp_re
[PATCH V4 05/11] megaraid_sas: SAS3.5 Generic Megaraid Controllers Fast Path for RAID 1/10 Writes
To improve RAID 1/10 Write performance, OS drivers need to issue the required Write IOs as Fast Path IOs (after the appropriate checks allowing Fast Path to be used) to the appropriate physical drives (translated from the OS logical IO) and wait for all Write IOs to complete. If any of the Write IOs fail or time out, the IO will be re issued to FW as an LD IO so FW can perform the error handling. This patch is depending on patch 4 Signed-off-by: Sasikumar Chandrasekaran --- drivers/scsi/megaraid/megaraid_sas.h| 1 + drivers/scsi/megaraid/megaraid_sas_fp.c | 31 ++- drivers/scsi/megaraid/megaraid_sas_fusion.c | 341 drivers/scsi/megaraid/megaraid_sas_fusion.h | 15 +- 4 files changed, 334 insertions(+), 54 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index d07b3e1..f4d6a94 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -2056,6 +2056,7 @@ struct megasas_instance { u16 max_num_sge; u16 max_fw_cmds; + u16 max_mpt_cmds; u16 max_mfi_cmds; u16 max_scsi_cmds; u16 ldio_threshold; diff --git a/drivers/scsi/megaraid/megaraid_sas_fp.c b/drivers/scsi/megaraid/megaraid_sas_fp.c index a4e213b..eb9ff44 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fp.c +++ b/drivers/scsi/megaraid/megaraid_sas_fp.c @@ -737,7 +737,7 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld, struct MR_DRV_RAID_MAP_ALL *map) { struct MR_LD_RAID *raid = MR_LdRaidGet(ld, map); - u32 pd, arRef; + u32 pd, arRef, r1_alt_pd; u8 physArm, span; u64 row; u8 retval = TRUE; @@ -772,9 +772,16 @@ static u8 mr_spanset_get_phy_params(struct megasas_instance *instance, u32 ld, arRef = MR_LdSpanArrayGet(ld, span, map); pd = MR_ArPdGet(arRef, physArm, map); - if (pd != MR_PD_INVALID) + if (pd != MR_PD_INVALID) { *pDevHandle = MR_PdDevHandleGet(pd, map); - else { + /* get second pd also for raid 1/10 fast path writes*/ + if (raid->level == 1) { + r1_alt_pd = MR_ArPdGet(arRef, physArm + 1, map); + if (r1_alt_pd != MR_PD_INVALID) + io_info->r1_alt_dev_handle = + MR_PdDevHandleGet(r1_alt_pd, map); + } + } else { *pDevHandle = cpu_to_le16(MR_PD_INVALID); if ((raid->level >= 5) && ((fusion->adapter_type == THUNDERBOLT_SERIES) || @@ -819,7 +826,7 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow, struct MR_DRV_RAID_MAP_ALL *map) { struct MR_LD_RAID *raid = MR_LdRaidGet(ld, map); - u32 pd, arRef; + u32 pd, arRef, r1_alt_pd; u8 physArm, span; u64 row; u8 retval = TRUE; @@ -867,10 +874,17 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow, arRef = MR_LdSpanArrayGet(ld, span, map); pd = MR_ArPdGet(arRef, physArm, map); /* Get the pd */ - if (pd != MR_PD_INVALID) + if (pd != MR_PD_INVALID) { /* Get dev handle from Pd. */ *pDevHandle = MR_PdDevHandleGet(pd, map); - else { + /* get second pd also for raid 1/10 fast path writes*/ + if (raid->level == 1) { + r1_alt_pd = MR_ArPdGet(arRef, physArm + 1, map); + if (r1_alt_pd != MR_PD_INVALID) + io_info->r1_alt_dev_handle = + MR_PdDevHandleGet(r1_alt_pd, map); + } + } else { /* set dev handle as invalid. */ *pDevHandle = cpu_to_le16(MR_PD_INVALID); if ((raid->level >= 5) && @@ -1126,6 +1140,11 @@ u8 MR_GetPhyParams(struct megasas_instance *instance, u32 ld, u64 stripRow, /* If IO on an invalid Pd, then FP is not possible.*/ if (io_info->devHandle == cpu_to_le16(MR_PD_INVALID)) io_info->fpOkForIo = FALSE; + /* set raid 1/10 fast path write capable bit in io_info */ + if (io_info->fpOkForIo && + (io_info->r1_alt_dev_handle != MR_PD_INVALID) && + (raid->level == 1) && !isRead) + io_info->is_raid_1_fp_write = 1; return retval; } else if (isRead) { uint stripIdx; diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 39dad6d..2fcd5cd 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -269,8 +269,15 @@ inline void megasas_
[PATCH V4 02/11] megaraid_sas: 128 MSIX Support
SAS3.5 Generic Megaraid based Controllers will have the support for 128 MSI-X vectors, resulting in the need to support 128 reply queues This patch is depending on patch 1 Signed-off-by: Sasikumar Chandrasekaran --- drivers/scsi/megaraid/megaraid_sas.h| 1 + drivers/scsi/megaraid/megaraid_sas_base.c | 24 +--- drivers/scsi/megaraid/megaraid_sas_fusion.c | 4 ++-- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 72e16c2..9d4ca8d 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -2149,6 +2149,7 @@ struct megasas_instance { bool dev_handle; bool fw_sync_cache_support; bool is_ventura; + bool msix_combined; }; struct MR_LD_VF_MAP { u32 size; diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index efccf98..c583e0b 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -5086,13 +5086,7 @@ static int megasas_init_fw(struct megasas_instance *instance) goto fail_ready_state; } - /* -* MSI-X host index 0 is common for all adapter. -* It is used for all MPT based Adapters. -*/ - instance->reply_post_host_index_addr[0] = - (u32 __iomem *)((u8 __iomem *)instance->reg_set + - MPI2_REPLY_POST_HOST_INDEX_OFFSET); + /* Check if MSI-X is supported while in ready state */ msix_enable = (instance->instancet->read_fw_status_reg(reg_set) & @@ -5110,6 +5104,9 @@ static int megasas_init_fw(struct megasas_instance *instance) instance->msix_vectors = ((scratch_pad_2 & MR_MAX_REPLY_QUEUES_EXT_OFFSET) >> MR_MAX_REPLY_QUEUES_EXT_OFFSET_SHIFT) + 1; + if (instance->msix_vectors > 16) + instance->msix_combined = true; + if (rdpq_enable) instance->is_rdpq = (scratch_pad_2 & MR_RDPQ_MODE_OFFSET) ? 1 : 0; @@ -5143,6 +5140,19 @@ static int megasas_init_fw(struct megasas_instance *instance) else instance->msix_vectors = 0; } + /* +* MSI-X host index 0 is common for all adapter. +* It is used for all MPT based Adapters. +*/ + if (instance->msix_combined) { + instance->reply_post_host_index_addr[0] = + (u32 *)((u8 *)instance->reg_set + + MPI2_SUP_REPLY_POST_HOST_INDEX_OFFSET); + } else { + instance->reply_post_host_index_addr[0] = + (u32 *)((u8 *)instance->reg_set + + MPI2_REPLY_POST_HOST_INDEX_OFFSET); + } dev_info(&instance->pdev->dev, "firmware supports msix\t: (%d)", fw_msix_count); diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c index 8d7a397..413e2030 100644 --- a/drivers/scsi/megaraid/megaraid_sas_fusion.c +++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c @@ -2391,7 +2391,7 @@ static void megasas_build_ld_nonrw_fusion(struct megasas_instance *instance, * pending to be completed */ if (threshold_reply_count >= THRESHOLD_REPLY_COUNT) { - if (fusion->adapter_type == INVADER_SERIES) + if (instance->msix_combined) writel(((MSIxIndex & 0x7) << 24) | fusion->last_reply_idx[MSIxIndex], instance->reply_post_host_index_addr[MSIxIndex/8]); @@ -2407,7 +2407,7 @@ static void megasas_build_ld_nonrw_fusion(struct megasas_instance *instance, return IRQ_NONE; wmb(); - if (fusion->adapter_type == INVADER_SERIES) + if (instance->msix_combined) writel(((MSIxIndex & 0x7) << 24) | fusion->last_reply_idx[MSIxIndex], instance->reply_post_host_index_addr[MSIxIndex/8]); -- 1.8.3.1 -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH V4 04/11] megaraid_sas: SAS3.5 Generic Megaraid Controllers Stream Detection and IO Coalescing
Detect sequential IO streams and pass those IOs directly to FW. This patch is depending on patch 3 Signed-off-by: Sasikumar Chandrasekaran --- drivers/scsi/megaraid/megaraid_sas.h| 5 +- drivers/scsi/megaraid/megaraid_sas_base.c | 43 +++- drivers/scsi/megaraid/megaraid_sas_fp.c | 2 + drivers/scsi/megaraid/megaraid_sas_fusion.c | 164 +++- drivers/scsi/megaraid/megaraid_sas_fusion.h | 117 +++- 5 files changed, 298 insertions(+), 33 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 9d4ca8d..d07b3e1 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -105,7 +105,7 @@ */ /* - * MFI stands for MegaRAID SAS FW Interface. This is just a moniker for + * MFI stands for MegaRAID SAS FW Interface. This is just a moniker for * protocol between the software and firmware. Commands are issued using * "message frames" */ @@ -1440,7 +1440,7 @@ enum FW_BOOT_CONTEXT { * register set for both 1068 and 1078 controllers * structure extended for 1078 registers */ - + struct megasas_register_set { u32 doorbell; /*h*/ u32 fusion_seq_offset; /*0004h*/ @@ -2070,6 +2070,7 @@ struct megasas_instance { /* used to sync fire the cmd to fw */ spinlock_t hba_lock; /* used to synch producer, consumer ptrs in dpc */ + spinlock_t stream_lock; spinlock_t completion_lock; struct dma_pool *frame_dma_pool; struct dma_pool *sense_dma_pool; diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index c583e0b..c52f7be 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -5015,7 +5015,7 @@ static int megasas_init_fw(struct megasas_instance *instance) struct megasas_register_set __iomem *reg_set; struct megasas_ctrl_info *ctrl_info = NULL; unsigned long bar_list; - int i, loop, fw_msix_count = 0; + int i, j, loop, fw_msix_count = 0; struct IOV_111 *iovPtr; struct fusion_context *fusion; @@ -5202,6 +5202,36 @@ static int megasas_init_fw(struct megasas_instance *instance) } memset(instance->ld_ids, 0xff, MEGASAS_MAX_LD_IDS); + + /* stream detection initialization */ + if (instance->is_ventura) { + fusion->stream_detect_by_ld = + kzalloc(sizeof(struct LD_STREAM_DETECT *) + * MAX_LOGICAL_DRIVES_EXT, + GFP_KERNEL); + if (!fusion->stream_detect_by_ld) { + dev_err(&instance->pdev->dev, + "unable to allocate stream detection for pool of LDs\n"); + goto fail_get_ld_pd_list; + } + for (i = 0; i < MAX_LOGICAL_DRIVES_EXT; ++i) { + fusion->stream_detect_by_ld[i] = + kmalloc(sizeof(struct LD_STREAM_DETECT), + GFP_KERNEL); + if (!fusion->stream_detect_by_ld[i]) { + dev_err(&instance->pdev->dev, + "unable to allocate stream detect by LD\n "); +for (j = 0; j < i; ++j) + kfree(fusion->stream_detect_by_ld[j]); + kfree(fusion->stream_detect_by_ld); + fusion->stream_detect_by_ld = NULL; + goto fail_get_ld_pd_list; + } + fusion->stream_detect_by_ld[i]->mru_bit_map + = MR_STREAM_BITMAP; + } + } + if (megasas_ld_list_query(instance, MR_LD_QUERY_TYPE_EXPOSED_TO_HOST)) megasas_get_ld_list(instance); @@ -5321,6 +5351,8 @@ static int megasas_init_fw(struct megasas_instance *instance) return 0; +fail_get_ld_pd_list: + instance->instancet->disable_intr(instance); fail_get_pd_list: instance->instancet->disable_intr(instance); megasas_destroy_irqs(instance); @@ -5854,6 +5886,7 @@ static int megasas_probe_one(struct pci_dev *pdev, spin_lock_init(&instance->mfi_pool_lock); spin_lock_init(&instance->hba_lock); + spin_lock_init(&instance->stream_lock); spin_lock_init(&instance->completion_lock); mutex_init(&instance->reset_mutex); @@ -6354,6 +6387,14 @@ static void megasas_detach_one(struct pci_dev *pdev) if (instance->msix_vectors) pci_disable_msix(instance->pdev); + if (instance->is_ventura) { + for (i = 0; i < MAX_LOGICAL_DRIVES_EXT; ++i) + kfree(fusion->stream_detect_by_ld[i]); + kfree(fu
[PATCH V4 08/11] megaraid_sas: Enable or Disable Fast path based on the PCI Threshold Bandwidth
Large SEQ IO workload should sent as non fast path commands This patch is depending on patch 7 Signed-off-by: Sasikumar Chandrasekaran --- drivers/scsi/megaraid/megaraid_sas.h| 8 + drivers/scsi/megaraid/megaraid_sas_base.c | 48 + drivers/scsi/megaraid/megaraid_sas_fp.c | 11 +-- drivers/scsi/megaraid/megaraid_sas_fusion.c | 20 +++- drivers/scsi/megaraid/megaraid_sas_fusion.h | 2 +- 5 files changed, 78 insertions(+), 11 deletions(-) diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h index 3e087ab..eb5be2b 100644 --- a/drivers/scsi/megaraid/megaraid_sas.h +++ b/drivers/scsi/megaraid/megaraid_sas.h @@ -1429,6 +1429,8 @@ enum FW_BOOT_CONTEXT { #define MFI_1068_FW_HANDSHAKE_OFFSET 0x64 #define MFI_1068_FW_READY 0x +#define MEGASAS_RAID1_FAST_PATH_STATUS_CHECK_INTERVAL HZ + #define MR_MAX_REPLY_QUEUES_OFFSET 0X001F #define MR_MAX_REPLY_QUEUES_EXT_OFFSET 0X003FC000 #define MR_MAX_REPLY_QUEUES_EXT_OFFSET_SHIFT14 @@ -2101,6 +2103,10 @@ struct megasas_instance { atomic_t ldio_outstanding; atomic_t fw_reset_no_pci_access; + atomic64_t bytes_wrote; /* used for raid1 fast path enable or disable */ + atomic_t r1_write_fp_capable; + + struct megasas_instance_template *instancet; struct tasklet_struct isr_tasklet; struct work_struct work_init; @@ -2143,6 +2149,7 @@ struct megasas_instance { long reset_flags; struct mutex reset_mutex; struct timer_list sriov_heartbeat_timer; + struct timer_list r1_fp_hold_timer; char skip_heartbeat_timer_del; u8 requestorId; char PlasmaFW111; @@ -2159,6 +2166,7 @@ struct megasas_instance { bool is_ventura; bool msix_combined; u16 max_raid_mapsize; + u64 pci_threshold_bandwidth; /* used to control the fp writes */ }; struct MR_LD_VF_MAP { u32 size; diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c index 8aafb59..899d25c 100644 --- a/drivers/scsi/megaraid/megaraid_sas_base.c +++ b/drivers/scsi/megaraid/megaraid_sas_base.c @@ -1940,6 +1940,9 @@ void megaraid_sas_kill_hba(struct megasas_instance *instance) } /* Complete outstanding ioctls when adapter is killed */ megasas_complete_outstanding_ioctls(instance); + if (instance->is_ventura) + del_timer_sync(&instance->r1_fp_hold_timer); + } /** @@ -2438,6 +2441,24 @@ void megasas_sriov_heartbeat_handler(unsigned long instance_addr) } } +/*Handler for disabling/enabling raid 1 fast paths*/ +void megasas_change_r1_fp_status(unsigned long instance_addr) +{ + struct megasas_instance *instance = + (struct megasas_instance *)instance_addr; + if (atomic64_read(&instance->bytes_wrote) >= + instance->pci_threshold_bandwidth) { + + atomic64_set(&instance->bytes_wrote, 0); + atomic_set(&instance->r1_write_fp_capable, 0); + } else { + atomic64_set(&instance->bytes_wrote, 0); + atomic_set(&instance->r1_write_fp_capable, 1); + } + mod_timer(&instance->r1_fp_hold_timer, +jiffies + MEGASAS_RAID1_FAST_PATH_STATUS_CHECK_INTERVAL); +} + /** * megasas_wait_for_outstanding - Wait for all outstanding cmds * @instance: Adapter soft state @@ -5371,6 +5392,17 @@ static int megasas_init_fw(struct megasas_instance *instance) instance->skip_heartbeat_timer_del = 1; } + if (instance->is_ventura) { + atomic64_set(&instance->bytes_wrote, 0); + atomic_set(&instance->r1_write_fp_capable, 1); + megasas_start_timer(instance, + &instance->r1_fp_hold_timer, + megasas_change_r1_fp_status, + MEGASAS_RAID1_FAST_PATH_STATUS_CHECK_INTERVAL); + dev_info(&instance->pdev->dev, "starting the raid 1 fp timer with interval %d\n", + MEGASAS_RAID1_FAST_PATH_STATUS_CHECK_INTERVAL); + } + return 0; fail_get_ld_pd_list: @@ -6161,6 +6193,9 @@ static void megasas_shutdown_controller(struct megasas_instance *instance, if (instance->requestorId && !instance->skip_heartbeat_timer_del) del_timer_sync(&instance->sriov_heartbeat_timer); + if (instance->is_ventura) + del_timer_sync(&instance->r1_fp_hold_timer); + megasas_flush_cache(instance); megasas_shutdown_controller(instance, MR_DCMD_HIBERNATE_SHUTDOWN); @@ -6280,6 +6315,16 @@ static void megasas_shutdown_controller(struct megasas_instance *instance, megasas_setup_jbod_map(instance); instance->unload = 0; + i
Re: [PATCH] scsi: avoid a permanent stop of the scsi device's request queue
Hi, Bart, On 2016/12/6 23:51, Bart Van Assche wrote: > On 12/06/16 01:12, Wei Fang wrote: >> The scsi device is being setted to the SDEV_RUNNING state at the end of >> the scan work. When the remote port reappears, scsi_target_unblock() >> will be called, but the QUEUE_FLAG_STOPPED flag will not be cleared, >> since scsi_internal_device_unblock() ignores SCSI devices in SDEV_RUNNING >> state. It results in a permanent stop of the scsi device's request >> queue. Every requests sended to it will be blocked. > > Hello Wei, > > scsi_device_set_state() does not allow the transition from > SDEV_CREATED_BLOCK to SDEV_RUNNING. If a SCSI device is blocked after it > has been added to the __devices list and before scsi_add_lun() finishes > then I think the scan code will change its state into SDEV_BLOCK. Are > you sure what you described above is what happened? Yes, we already encountered this case on out machine: The state of the scsi device first is changed to SDEV_BLOCK in scsi_add_lun() as you metioned, then it will be changed to SDEV_RUNNING in scsi_sysfs_add_sdev(). Thanks, Wei -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] scsi: avoid a permanent stop of the scsi device's request queue
On 12/06/16 17:21, Wei Fang wrote: > The state of the scsi device first is changed to SDEV_BLOCK in > scsi_add_lun() as you mentioned, then it will be changed to SDEV_RUNNING > in scsi_sysfs_add_sdev(). Hello Wei, The purpose of the scsi_device_set_state(sdev, SDEV_RUNNING) call in scsi_sysfs_add_sdev() is to change the device state from SDEV_CREATED into SDEV_RUNNING. Have you tried to modify scsi_sysfs_add_sdev() such that it only changes the device state into SDEV_RUNNING if the current state is SDEV_CREATED and also such that it changes SDEV_CREATED_BLOCK into SDEV_BLOCK? Thanks, Bart. -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] scsi: avoid a permanent stop of the scsi device's request queue
Hi, Bart, On 2016/12/7 10:45, Bart Van Assche wrote: > On 12/06/16 17:21, Wei Fang wrote: >> The state of the scsi device first is changed to SDEV_BLOCK in >> scsi_add_lun() as you mentioned, then it will be changed to SDEV_RUNNING >> in scsi_sysfs_add_sdev(). > > Hello Wei, > > The purpose of the scsi_device_set_state(sdev, SDEV_RUNNING) call in > scsi_sysfs_add_sdev() is to change the device state from SDEV_CREATED > into SDEV_RUNNING. Have you tried to modify scsi_sysfs_add_sdev() such > that it only changes the device state into SDEV_RUNNING if the current > state is SDEV_CREATED and also such that it changes SDEV_CREATED_BLOCK > into SDEV_BLOCK? Does those code in scsi_add_lun() have done this thing? ... ret = scsi_device_set_state(sdev, SDEV_RUNNING); if (ret) { ret = scsi_device_set_state(sdev, SDEV_BLOCK); ... } ... You mean we shouldn't change the device state from SDEV_BLOCK into SDEV_RUNNING in scsi_sysfs_add_sdev()? I thought it doesn't matter that the state is changed from SDEV_BLOCK to SDEV_RUNNING in scsi_sysfs_add_sdev(), if the queue can be unblocked in scsi_internal_device_unblock() in SDEV_RUNNING state. But it was broken since commit 5c10e63c943b. Thanks, Wei -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] scsi: avoid a permanent stop of the scsi device's request queue
On 12/06/16 19:41, Wei Fang wrote: > On 2016/12/7 10:45, Bart Van Assche wrote: >> The purpose of the scsi_device_set_state(sdev, SDEV_RUNNING) call in >> scsi_sysfs_add_sdev() is to change the device state from SDEV_CREATED >> into SDEV_RUNNING. Have you tried to modify scsi_sysfs_add_sdev() such >> that it only changes the device state into SDEV_RUNNING if the current >> state is SDEV_CREATED and also such that it changes SDEV_CREATED_BLOCK >> into SDEV_BLOCK? > > Does those code in scsi_add_lun() have done this thing? > ... > ret = scsi_device_set_state(sdev, SDEV_RUNNING); > if (ret) { > ret = scsi_device_set_state(sdev, SDEV_BLOCK); > ... > } > ... > You mean we shouldn't change the device state from SDEV_BLOCK > into SDEV_RUNNING in scsi_sysfs_add_sdev()? > > I thought it doesn't matter that the state is changed from SDEV_BLOCK > to SDEV_RUNNING in scsi_sysfs_add_sdev(), if the queue can be unblocked > in scsi_internal_device_unblock() in SDEV_RUNNING state. But it > was broken since commit 5c10e63c943b. Hello Wei, I am aware that commit 5c10e63c943b caused the behavior change. But that doesn't mean that a fix has to undo the changes introduced by that commit. We do not only want to make sure that the SCSI core works as intended but also that the SCSI core code is as easy to comprehend as reasonably possible. Adding "&& sdev->sdev_state != SDEV_RUNNING" in scsi_internal_device_unblock() would require a long comment to explain why that code has been added. I think modifying scsi_sysfs_add_sdev() such that it does not unblock devices will result in code that is easier to understand. Bart. -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] net: return value of skb_linearize should be handled in Linux kernel
On Mon, Dec 5, 2016 at 11:10 PM, Zhouyi Zhou wrote: > diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c > b/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c > index 2a653ec..ab787cb 100644 > --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c > +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c > @@ -490,7 +490,11 @@ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter, > */ > if ((fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA) && > (fctl & FC_FC_END_SEQ)) { > - skb_linearize(skb); > + int err = 0; > + > + err = skb_linearize(skb); > + if (err) > + return err; You can reuse 'rc' instead of adding 'err'. > crc = (struct fcoe_crc_eof *)skb_put(skb, sizeof(*crc)); > crc->fcoe_eof = FC_EOF_T; > } > diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c > b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c > index fee1f29..4926d48 100644 > --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c > +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c > @@ -2173,8 +2173,7 @@ static int ixgbe_clean_rx_irq(struct ixgbe_q_vector > *q_vector, > total_rx_bytes += ddp_bytes; > total_rx_packets += DIV_ROUND_UP(ddp_bytes, > mss); > - } > - if (!ddp_bytes) { > + } else { > dev_kfree_skb_any(skb); > continue; > } This piece doesn't seem to be related. -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2] qla4xxx: switch to pci_alloc_irq_vectors
On 06/12/16, 7:26 PM, "Christoph Hellwig" wrote: >And simplify the MSI-X logic in general - just request the two >vectors directly instead of going through an indirection table. > >Signed-off-by: Christoph Hellwig >--- > drivers/scsi/qla4xxx/ql4_def.h | 18 + > drivers/scsi/qla4xxx/ql4_glbl.h | 1 - > drivers/scsi/qla4xxx/ql4_isr.c | 27 + > drivers/scsi/qla4xxx/ql4_nx.c | 89 >+++-- > 4 files changed, 37 insertions(+), 98 deletions(-) > >diff --git a/drivers/scsi/qla4xxx/ql4_def.h >b/drivers/scsi/qla4xxx/ql4_def.h >index a7cfc27..aeebefb 100644 >--- a/drivers/scsi/qla4xxx/ql4_def.h >+++ b/drivers/scsi/qla4xxx/ql4_def.h >@@ -409,18 +409,9 @@ struct qla4_8xxx_legacy_intr_set { > > /* MSI-X Support */ > >-#define QLA_MSIX_DEFAULT 0x00 >-#define QLA_MSIX_RSP_Q0x01 >- >+#define QLA_MSIX_DEFAULT 0 >+#define QLA_MSIX_RSP_Q1 > #define QLA_MSIX_ENTRIES 2 >-#define QLA_MIDX_DEFAULT 0 >-#define QLA_MIDX_RSP_Q1 >- >-struct ql4_msix_entry { >- int have_irq; >- uint16_t msix_vector; >- uint16_t msix_entry; >-}; > > /* > * ISP Operations >@@ -572,9 +563,6 @@ struct scsi_qla_host { > #define AF_IRQ_ATTACHED 10 /* 0x0400 */ > #define AF_DISABLE_ACB_COMPLETE 11 /* 0x0800 */ > #define AF_HA_REMOVAL 12 /* 0x1000 */ >-#define AF_INTx_ENABLED 15 /* 0x8000 */ >-#define AF_MSI_ENABLED16 /* 0x0001 */ >-#define AF_MSIX_ENABLED 17 /* 0x0002 */ > #define AF_MBOX_COMMAND_NOPOLL18 /* 0x0004 */ > #define AF_FW_RECOVERY19 /* 0x0008 */ > #define AF_EEH_BUSY 20 /* 0x0010 */ >@@ -762,8 +750,6 @@ struct scsi_qla_host { > struct isp_operations *isp_ops; > struct ql82xx_hw_data hw; > >- struct ql4_msix_entry msix_entries[QLA_MSIX_ENTRIES]; >- > uint32_t nx_dev_init_timeout; > uint32_t nx_reset_timeout; > void *fw_dump; >diff --git a/drivers/scsi/qla4xxx/ql4_glbl.h >b/drivers/scsi/qla4xxx/ql4_glbl.h >index 2559144..bce96a5 100644 >--- a/drivers/scsi/qla4xxx/ql4_glbl.h >+++ b/drivers/scsi/qla4xxx/ql4_glbl.h >@@ -134,7 +134,6 @@ int qla4_8xxx_get_flash_info(struct scsi_qla_host >*ha); > void qla4_82xx_enable_intrs(struct scsi_qla_host *ha); > void qla4_82xx_disable_intrs(struct scsi_qla_host *ha); > int qla4_8xxx_enable_msix(struct scsi_qla_host *ha); >-void qla4_8xxx_disable_msix(struct scsi_qla_host *ha); > irqreturn_t qla4_8xxx_msi_handler(int irq, void *dev_id); > irqreturn_t qla4_8xxx_default_intr_handler(int irq, void *dev_id); > irqreturn_t qla4_8xxx_msix_rsp_q(int irq, void *dev_id); >diff --git a/drivers/scsi/qla4xxx/ql4_isr.c >b/drivers/scsi/qla4xxx/ql4_isr.c >index 4f9c0f2..d2cd33d 100644 >--- a/drivers/scsi/qla4xxx/ql4_isr.c >+++ b/drivers/scsi/qla4xxx/ql4_isr.c >@@ -1107,7 +1107,7 @@ static void qla4_82xx_spurious_interrupt(struct >scsi_qla_host *ha, > DEBUG2(ql4_printk(KERN_INFO, ha, "Spurious Interrupt\n")); > if (is_qla8022(ha)) { > writel(0, &ha->qla4_82xx_reg->host_int); >- if (test_bit(AF_INTx_ENABLED, &ha->flags)) >+ if (!ha->pdev->msi_enabled && !ha->pdev->msix_enabled) > qla4_82xx_wr_32(ha, ha->nx_legacy_intr.tgt_mask_reg, > 0xfbff); > } >@@ -1564,19 +1564,18 @@ int qla4xxx_request_irqs(struct scsi_qla_host *ha) > > try_msi: > /* Trying MSI */ >- ret = pci_enable_msi(ha->pdev); >- if (!ret) { >+ ret = pci_alloc_irq_vectors(ha->pdev, 1, 1, PCI_IRQ_MSI); >+ if (ret > 0) { > ret = request_irq(ha->pdev->irq, qla4_8xxx_msi_handler, > 0, DRIVER_NAME, ha); > if (!ret) { > DEBUG2(ql4_printk(KERN_INFO, ha, "MSI: Enabled.\n")); >- set_bit(AF_MSI_ENABLED, &ha->flags); > goto irq_attached; > } else { > ql4_printk(KERN_WARNING, ha, > "MSI: Failed to reserve interrupt %d " > "already in use.\n", ha->pdev->irq); >- pci_disable_msi(ha->pdev); >+ pci_free_irq_vectors(ha->pdev); > } > } > >@@ -1592,7 +1591,6 @@ int qla4xxx_request_irqs(struct scsi_qla_host *ha) > IRQF_SHARED, DRIVER_NAME, ha); > if (!ret) { > DEBUG2(ql4_printk(KERN_INFO, ha, "INTx: Enabled.\n")); >- set_bit(AF_INTx_ENABLED, &ha->flags); > goto irq_attached; > > } else { >@@ -1614,14 +1612,11 @@ int qla4xxx_request_irqs(struct scsi_qla_host *ha) > > void qla4xxx_free_irqs(struct scsi_qla_host *ha) > { >- if (test_and_clear_bit(AF_IRQ_ATTACHED, &ha->flags)) { >- if (test_bit(AF_MSIX_ENABLED, &ha->flags)) { >-
Re: [PATCH 10/10] virtio: enable endian checks for sparse builds
On 2016年12月06日 23:41, Michael S. Tsirkin wrote: __CHECK_ENDIAN__ isn't on by default presumably because it triggers too many sparse warnings for correct code. But virtio is now clean of these warnings, and we want to keep it this way - enable this for sparse builds. Signed-off-by: Michael S. Tsirkin --- It seems that there should be a better way to do it, but this works too. Reviewed-by: Jason Wang drivers/block/Makefile | 1 + drivers/char/Makefile | 1 + drivers/char/hw_random/Makefile | 2 ++ drivers/gpu/drm/virtio/Makefile | 1 + drivers/net/Makefile| 3 +++ drivers/net/caif/Makefile | 1 + drivers/rpmsg/Makefile | 1 + drivers/s390/virtio/Makefile| 2 ++ drivers/scsi/Makefile | 1 + drivers/vhost/Makefile | 1 + drivers/virtio/Makefile | 3 +++ net/9p/Makefile | 1 + net/packet/Makefile | 1 + net/vmw_vsock/Makefile | 2 ++ 14 files changed, 21 insertions(+) diff --git a/drivers/block/Makefile b/drivers/block/Makefile index 1e9661e..597481c 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile @@ -27,6 +27,7 @@ obj-$(CONFIG_BLK_DEV_OSD) += osdblk.o obj-$(CONFIG_BLK_DEV_UMEM)+= umem.o obj-$(CONFIG_BLK_DEV_NBD) += nbd.o obj-$(CONFIG_BLK_DEV_CRYPTOLOOP) += cryptoloop.o +CFLAGS_virtio_blk.o += -D__CHECK_ENDIAN__ obj-$(CONFIG_VIRTIO_BLK) += virtio_blk.o obj-$(CONFIG_BLK_DEV_SX8) += sx8.o diff --git a/drivers/char/Makefile b/drivers/char/Makefile index 6e6c244..a99467d 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile @@ -6,6 +6,7 @@ obj-y += mem.o random.o obj-$(CONFIG_TTY_PRINTK) += ttyprintk.o obj-y += misc.o obj-$(CONFIG_ATARI_DSP56K)+= dsp56k.o +CFLAGS_virtio_console.o += -D__CHECK_ENDIAN__ obj-$(CONFIG_VIRTIO_CONSOLE) += virtio_console.o obj-$(CONFIG_RAW_DRIVER) += raw.o obj-$(CONFIG_SGI_SNSC)+= snsc.o snsc_event.o diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile index 5f52b1e..a2b0931 100644 --- a/drivers/char/hw_random/Makefile +++ b/drivers/char/hw_random/Makefile @@ -17,6 +17,8 @@ obj-$(CONFIG_HW_RANDOM_IXP4XX) += ixp4xx-rng.o obj-$(CONFIG_HW_RANDOM_OMAP) += omap-rng.o obj-$(CONFIG_HW_RANDOM_OMAP3_ROM) += omap3-rom-rng.o obj-$(CONFIG_HW_RANDOM_PASEMI) += pasemi-rng.o +CFLAGS_virtio_transport.o += -D__CHECK_ENDIAN__ +CFLAGS_virtio-rng.o += -D__CHECK_ENDIAN__ obj-$(CONFIG_HW_RANDOM_VIRTIO) += virtio-rng.o obj-$(CONFIG_HW_RANDOM_TX4939) += tx4939-rng.o obj-$(CONFIG_HW_RANDOM_MXC_RNGA) += mxc-rnga.o diff --git a/drivers/gpu/drm/virtio/Makefile b/drivers/gpu/drm/virtio/Makefile index 3fb8eac..1162366 100644 --- a/drivers/gpu/drm/virtio/Makefile +++ b/drivers/gpu/drm/virtio/Makefile @@ -3,6 +3,7 @@ # Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. ccflags-y := -Iinclude/drm +ccflags-y += -D__CHECK_ENDIAN__ virtio-gpu-y := virtgpu_drv.o virtgpu_kms.o virtgpu_drm_bus.o virtgpu_gem.o \ virtgpu_fb.o virtgpu_display.o virtgpu_vq.o virtgpu_ttm.o \ diff --git a/drivers/net/Makefile b/drivers/net/Makefile index 7336cbd..3f587de 100644 --- a/drivers/net/Makefile +++ b/drivers/net/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_EQUALIZER) += eql.o obj-$(CONFIG_IFB) += ifb.o obj-$(CONFIG_MACSEC) += macsec.o obj-$(CONFIG_MACVLAN) += macvlan.o +CFLAGS_macvtap.o += -D__CHECK_ENDIAN__ obj-$(CONFIG_MACVTAP) += macvtap.o obj-$(CONFIG_MII) += mii.o obj-$(CONFIG_MDIO) += mdio.o @@ -20,8 +21,10 @@ obj-$(CONFIG_NETCONSOLE) += netconsole.o obj-$(CONFIG_PHYLIB) += phy/ obj-$(CONFIG_RIONET) += rionet.o obj-$(CONFIG_NET_TEAM) += team/ +CFLAGS_tun.o += -D__CHECK_ENDIAN__ obj-$(CONFIG_TUN) += tun.o obj-$(CONFIG_VETH) += veth.o +CFLAGS_virtio_net.o += -D__CHECK_ENDIAN__ obj-$(CONFIG_VIRTIO_NET) += virtio_net.o obj-$(CONFIG_VXLAN) += vxlan.o obj-$(CONFIG_GENEVE) += geneve.o diff --git a/drivers/net/caif/Makefile b/drivers/net/caif/Makefile index 9bbd453..d1a922c 100644 --- a/drivers/net/caif/Makefile +++ b/drivers/net/caif/Makefile @@ -12,3 +12,4 @@ obj-$(CONFIG_CAIF_HSI) += caif_hsi.o # Virtio interface obj-$(CONFIG_CAIF_VIRTIO) += caif_virtio.o +CFLAGS_caif_virtio.o += -D__CHECK_ENDIAN__ diff --git a/drivers/rpmsg/Makefile b/drivers/rpmsg/Makefile index ae9c913..23c8b66 100644 --- a/drivers/rpmsg/Makefile +++ b/drivers/rpmsg/Makefile @@ -1,3 +1,4 @@ obj-$(CONFIG_RPMSG) += rpmsg_core.o obj-$(CONFIG_RPMSG_QCOM_SMD) += qcom_smd.o obj-$(CONFIG_RPMSG_VIRTIO)+= virtio_rpmsg_bus.o +CFLAGS_virtio_rpmsg_bus.o += -D__CHECK_ENDIAN__ diff --git a/drivers/s390/virtio/Makefile b/drivers/s390/virtio/Makefile index df40692..270ada5 100644 --- a/drivers/s390/virtio/Makefile +++ b/drivers/s390/virtio/Makefile @@ -6,6 +6,8 @@ # it under the terms of the GNU General Public License (version 2 only) # as published by the Free
Re: [PATCH] scsi: hisi_sas: support deferred probe for v2 hw
On 2016年12月06日 20:44, John Garry wrote: In the hip06 and hip07 SoCs, the interrupt lines from the SAS controllers are connected to mbigen hw module [1]. The mbigen module is probed with module_init, and, as such, is not guaranteed to probe before the SAS driver. So we need to support deferred probe. We check for probe deferral in the hw layer probe, so we not probe into the main layer and allocate shost, memories, etc., to later learn that we need to defer the probe. [1] ./Documentation/devicetree/bindings/interrupt-controller/hisilicon,mbigen-v2.txt Signed-off-by: John Garry Reviewed-by: Zhangfei Gao Thanks -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 10/10] virtio: enable endian checks for sparse builds
On Tue, 2016-12-06 at 17:41 +0200, Michael S. Tsirkin wrote: > It seems that there should be a better way to do it, > but this works too. In some cases there might be: > --- a/drivers/s390/virtio/Makefile > +++ b/drivers/s390/virtio/Makefile > @@ -6,6 +6,8 @@ > # it under the terms of the GNU General Public License (version 2 > only) > # as published by the Free Software Foundation. > > +CFLAGS_virtio_ccw.o += -D__CHECK_ENDIAN__ > +CFLAGS_kvm_virtio.o += -D__CHECK_ENDIAN__ > s390-virtio-objs := virtio_ccw.o > ifdef CONFIG_S390_GUEST_OLD_TRANSPORT > s390-virtio-objs += kvm_virtio.o Here you could use ccflags-y += -D__CHECK_ENDIAN__ for example, or even subdir-ccflags-y += -D__CHECK_ENDIAN__ (in case any subdirs ever get added here) > --- a/drivers/vhost/Makefile > +++ b/drivers/vhost/Makefile > @@ -1,3 +1,4 @@ > +ccflags-y := -D__CHECK_ENDIAN__ Looks like you did that here and in some other places though - so perhaps the s390 one was intentionally different? > --- a/net/packet/Makefile > +++ b/net/packet/Makefile > @@ -2,6 +2,7 @@ > # Makefile for the packet AF. > # > > +ccflags-y := -D__CHECK_ENDIAN__ Technically this is slightly more than advertised, but I guess that still makes sense if it's clean now. johannes -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] net: return value of skb_linearize should be handled in Linux kernel
On Wed, Dec 7, 2016 at 1:02 PM, Cong Wang wrote: > On Mon, Dec 5, 2016 at 11:10 PM, Zhouyi Zhou wrote: >> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c >> b/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c >> index 2a653ec..ab787cb 100644 >> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c >> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c >> @@ -490,7 +490,11 @@ int ixgbe_fcoe_ddp(struct ixgbe_adapter *adapter, >> */ >> if ((fh->fh_r_ctl == FC_RCTL_DD_SOL_DATA) && >> (fctl & FC_FC_END_SEQ)) { >> - skb_linearize(skb); >> + int err = 0; >> + >> + err = skb_linearize(skb); >> + if (err) >> + return err; > > > You can reuse 'rc' instead of adding 'err'. rc here is meaningful for the length of data being ddped. If using rc here, a successful skb_linearize will assign rc to 0. > > > >> crc = (struct fcoe_crc_eof *)skb_put(skb, sizeof(*crc)); >> crc->fcoe_eof = FC_EOF_T; >> } >> diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c >> b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c >> index fee1f29..4926d48 100644 >> --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c >> +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c >> @@ -2173,8 +2173,7 @@ static int ixgbe_clean_rx_irq(struct ixgbe_q_vector >> *q_vector, >> total_rx_bytes += ddp_bytes; >> total_rx_packets += DIV_ROUND_UP(ddp_bytes, >> mss); >> - } >> - if (!ddp_bytes) { >> + } else { >> dev_kfree_skb_any(skb); >> continue; >> } > > > This piece doesn't seem to be related. if ddp_bytes is negative there will be some error, I think the skb should not pass to upper layer. -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] net: return value of skb_linearize should be handled in Linux kernel
On Tue, 2016-12-06 at 15:10 +0800, Zhouyi Zhou wrote: > kmalloc_reserve may fail to allocate memory inside skb_linearize, > which means skb_linearize's return value should not be ignored. > Following patch correct the uses of skb_linearize. > > Compiled in x86_64 > > Signed-off-by: Zhouyi Zhou > --- > drivers/infiniband/hw/nes/nes_nic.c | 5 +++-- > drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.c | 6 +- > drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 3 +-- > drivers/scsi/bnx2fc/bnx2fc_fcoe.c | 7 +-- > drivers/scsi/fcoe/fcoe.c | 5 - > net/tipc/link.c | 3 ++- > net/tipc/name_distr.c | 5 - > 7 files changed, 24 insertions(+), 10 deletions(-) > > diff --git a/drivers/infiniband/hw/nes/nes_nic.c > b/drivers/infiniband/hw/nes/nes_nic.c > index 2b27d13..69372ea 100644 > --- a/drivers/infiniband/hw/nes/nes_nic.c > +++ b/drivers/infiniband/hw/nes/nes_nic.c > @@ -662,10 +662,11 @@ static int nes_netdev_start_xmit(struct sk_buff *skb, > struct net_device *netdev) > nesnic->sq_head &= nesnic->sq_size-1; > } > } else { > - nesvnic->linearized_skbs++; > hoffset = skb_transport_header(skb) - skb->data; > nhoffset = skb_network_header(skb) - skb->data; > - skb_linearize(skb); > + if (skb_linearize(skb)) > + return NETDEV_TX_BUSY; This would live lock. Please drop the packet. You probably should send one patch per driver, to ease code review and acceptance. -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] scsi: avoid a permanent stop of the scsi device's request queue
Hi, Bart, On 2016/12/7 12:40, Bart Van Assche wrote: > I am aware that commit 5c10e63c943b caused the behavior change. But that > doesn't mean that a fix has to undo the changes introduced by that > commit. We do not only want to make sure that the SCSI core works as > intended but also that the SCSI core code is as easy to comprehend as > reasonably possible. Adding "&& sdev->sdev_state != SDEV_RUNNING" in > scsi_internal_device_unblock() would require a long comment to explain > why that code has been added. I think modifying scsi_sysfs_add_sdev() > such that it does not unblock devices will result in code that is easier > to understand. Agree that we should make the code easier to comprehend if possible :) If we modify scsi_sysfs_add_sdev() as below: ... if (scsi_device_created(sdev)) error = scsi_device_set_state(sdev, SDEV_RUNNING); if (error) error = scsi_device_set_state(sdev, SDEV_BLOCK); ... there's a chance that the state will be changed to SDEV_RUNNING. If a SCSI device is blocked after the check of the device's creating and before being changed to SDEV_RUNNING state, the state will still become SDEV_RUNNING. If we fix this problem in this way, we need introduce a way to synchronize those code. Actually I don't know quite well about the synchronization of scsi_device_set_state(). There are so many cases it can be called simultaneously, will the state become a unpredictable value, or this is tolerated? Thanks, Wei -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 10/10] virtio: enable endian checks for sparse builds
On Tue, Dec 06, 2016 at 05:41:05PM +0200, Michael S. Tsirkin wrote: > __CHECK_ENDIAN__ isn't on by default presumably because > it triggers too many sparse warnings for correct code. > But virtio is now clean of these warnings, and > we want to keep it this way - enable this for > sparse builds. > > Signed-off-by: Michael S. Tsirkin Nah. Please just enable it globally when using sparse. I actually had a chat with Linus about that a while ago and he seemed generally fine with it, I just didn't manage to actually do it.. -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH V4 00/11] megaraid_sas: Updates for scsi-next
This seems to be missing the pci_alloc_irq_vectors conversion from Hannes? -- To unsubscribe from this list: send the line "unsubscribe linux-scsi" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html