Re: [PATCH v2] storvsc: add logging for error/warning messages
> "Long" == Long Liwrites: Long> Introduce a logging level for storvsc to log certain error/warning Long> messages. Those messages are helpful in some environments, Long> e.g. Microsoft Azure, for customer support and troubleshooting Long> purposes. Applied to 4.5/scsi-queue. -- Martin K. Petersen Oracle Linux Engineering -- 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 09/13] IB/srpt: use the new CQ API
On 12/07/2015 12:51 PM, Christoph Hellwig wrote: [ ... ] Reviewed-by: Bart Van Assche-- 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/15] dm kcopyd: change mutex to spinlock
job->lock is only taken for a finite amount of time and the process doesn't block while holding it, so change it from mutex to spinlock. This change is needed for the next patch that makes it possible to call segment_complete from an interrupt. Taking mutexes inside an interrupt is not allowed. Signed-off-by: Mikulas Patocka--- drivers/md/dm-kcopyd.c | 10 +- 1 file changed, 5 insertions(+), 5 deletions(-) Index: linux-3.16-rc5/drivers/md/dm-kcopyd.c === --- linux-3.16-rc5.orig/drivers/md/dm-kcopyd.c 2014-07-15 19:20:34.0 +0200 +++ linux-3.16-rc5/drivers/md/dm-kcopyd.c 2014-07-15 19:24:20.0 +0200 @@ -21,7 +21,7 @@ #include #include #include -#include +#include #include #include #include @@ -356,7 +356,7 @@ struct kcopyd_job { * These fields are only used if the job has been split * into more manageable parts. */ - struct mutex lock; + spinlock_t lock; atomic_t sub_jobs; sector_t progress; @@ -629,7 +629,7 @@ static void segment_complete(int read_er struct kcopyd_job *job = sub_job->master_job; struct dm_kcopyd_client *kc = job->kc; - mutex_lock(>lock); + spin_lock(>lock); /* update the error */ if (read_err) @@ -653,7 +653,7 @@ static void segment_complete(int read_er job->progress += count; } } - mutex_unlock(>lock); + spin_unlock(>lock); if (count) { int i; @@ -708,7 +708,7 @@ static void submit_job(struct kcopyd_job if (job->source.count <= SUB_JOB_SIZE) dispatch_job(job); else { - mutex_init(>lock); + spin_lock_init(>lock); job->progress = 0; split_job(job); } -- 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 13/15] dm kcopyd: support copy offload
This patch adds copy offload support to dm-kcopyd. If copy offload fails, copying is performed using dm-io, just like before. There is a module parameter "copy_offload" that can be set to enable or disable this feature. It can be used to test performance of copy offload. Signed-off-by: Mikulas Patocka--- drivers/md/dm-kcopyd.c | 44 1 file changed, 40 insertions(+), 4 deletions(-) Index: linux-3.18-rc3/drivers/md/dm-kcopyd.c === --- linux-3.18-rc3.orig/drivers/md/dm-kcopyd.c 2014-11-05 18:09:23.0 +0100 +++ linux-3.18-rc3/drivers/md/dm-kcopyd.c 2014-11-05 18:13:04.0 +0100 @@ -96,6 +96,9 @@ static DEFINE_SPINLOCK(throttle_spinlock */ #define MAX_SLEEPS 10 +static bool copy_offload = true; +module_param(copy_offload, bool, S_IRUGO | S_IWUSR); + static void io_job_start(struct dm_kcopyd_throttle *t) { unsigned throttle, now, difference; @@ -358,6 +361,8 @@ struct kcopyd_job { sector_t progress; struct kcopyd_job *master_job; + + struct work_struct copy_work; }; static struct kmem_cache *_job_cache; @@ -709,6 +714,31 @@ static void submit_job(struct kcopyd_job } } +static void copy_offload_work(struct work_struct *work) +{ + struct kcopyd_job *job = container_of(work, struct kcopyd_job, copy_work); + sector_t copied; + + blkdev_issue_copy(job->source.bdev, job->source.sector, + job->dests[0].bdev, job->dests[0].sector, + job->source.count, + GFP_NOIO | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN, + NULL, NULL, ); + + job->source.sector += copied; + job->source.count -= copied; + job->dests[0].sector += copied; + job->dests[0].count -= copied; + + submit_job(job); +} + +static void try_copy_offload(struct kcopyd_job *job) +{ + INIT_WORK(>copy_work, copy_offload_work); + queue_work(job->kc->kcopyd_wq, >copy_work); +} + int dm_kcopyd_copy(struct dm_kcopyd_client *kc, struct dm_io_region *from, unsigned int num_dests, struct dm_io_region *dests, unsigned int flags, dm_kcopyd_notify_fn fn, void *context) @@ -733,10 +763,20 @@ int dm_kcopyd_copy(struct dm_kcopyd_clie job->num_dests = num_dests; memcpy(>dests, dests, sizeof(*dests) * num_dests); + job->fn = fn; + job->context = context; + job->master_job = job; + if (from) { job->source = *from; job->pages = NULL; job->rw = READ; + if (copy_offload && num_dests == 1 && + bdev_copy_offload(job->source.bdev) && + bdev_copy_offload(job->dests[0].bdev)) { + try_copy_offload(job); + return 0; + } } else { memset(>source, 0, sizeof job->source); job->source.count = job->dests[0].count; @@ -753,10 +793,6 @@ int dm_kcopyd_copy(struct dm_kcopyd_clie } } - job->fn = fn; - job->context = context; - job->master_job = job; - submit_job(job); return 0; -- 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 12/15] dm kcopyd: introduce the function submit_job
We move some code to a function submit_job. It is needed for the next patch that calls submit_job from another place. Signed-off-by: Mikulas Patocka--- drivers/md/dm-kcopyd.c | 19 --- 1 file changed, 12 insertions(+), 7 deletions(-) Index: linux-3.16-rc5/drivers/md/dm-kcopyd.c === --- linux-3.16-rc5.orig/drivers/md/dm-kcopyd.c 2014-07-14 16:45:23.0 +0200 +++ linux-3.16-rc5/drivers/md/dm-kcopyd.c 2014-07-14 17:28:36.0 +0200 @@ -698,6 +698,17 @@ static void split_job(struct kcopyd_job } } +static void submit_job(struct kcopyd_job *job) +{ + if (job->source.count <= SUB_JOB_SIZE) + dispatch_job(job); + else { + mutex_init(>lock); + job->progress = 0; + split_job(job); + } +} + int dm_kcopyd_copy(struct dm_kcopyd_client *kc, struct dm_io_region *from, unsigned int num_dests, struct dm_io_region *dests, unsigned int flags, dm_kcopyd_notify_fn fn, void *context) @@ -746,13 +757,7 @@ int dm_kcopyd_copy(struct dm_kcopyd_clie job->context = context; job->master_job = job; - if (job->source.count <= SUB_JOB_SIZE) - dispatch_job(job); - else { - mutex_init(>lock); - job->progress = 0; - split_job(job); - } + submit_job(job); return 0; } -- 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 11/15] dm stripe: support copy
Support the copy operation for the stripe target. In stripe_merge, we verify that the underlying device supports copy. If it doesn't, we can fail fast without any bio being contructed. Signed-off-by: Mikulas Patocka--- drivers/md/dm-stripe.c |1 + 1 file changed, 1 insertion(+) Index: linux-4.3-rc1/drivers/md/dm-stripe.c === --- linux-4.3-rc1.orig/drivers/md/dm-stripe.c 2015-09-14 16:06:36.0 +0200 +++ linux-4.3-rc1/drivers/md/dm-stripe.c2015-09-14 16:23:01.0 +0200 @@ -169,6 +169,7 @@ static int stripe_ctr(struct dm_target * ti->num_flush_bios = stripes; ti->num_discard_bios = stripes; ti->num_write_same_bios = stripes; + ti->copy_supported = 1; sc->chunk_size = chunk_size; if (chunk_size & (chunk_size - 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/15] dm kcopyd: call copy offload with asynchronous callback
Change dm kcopyd so that it calls blkdev_issue_copy with an asynchronous callback. There can be large number of pending kcopyd requests and holding a process context for each of them may put too much load on the workqueue subsystem. This patch changes it so that blkdev_issue_copy returns after it submitted the requests and copy_offload_callback is called when the copy operation finishes. Signed-off-by: Mikulas Patocka--- drivers/md/dm-kcopyd.c | 33 ++--- 1 file changed, 14 insertions(+), 19 deletions(-) Index: linux-3.16-rc5/drivers/md/dm-kcopyd.c === --- linux-3.16-rc5.orig/drivers/md/dm-kcopyd.c 2014-07-15 19:24:20.0 +0200 +++ linux-3.16-rc5/drivers/md/dm-kcopyd.c 2014-07-15 19:24:54.0 +0200 @@ -361,8 +361,6 @@ struct kcopyd_job { sector_t progress; struct kcopyd_job *master_job; - - struct work_struct copy_work; }; static struct kmem_cache *_job_cache; @@ -628,8 +626,9 @@ static void segment_complete(int read_er struct kcopyd_job *sub_job = (struct kcopyd_job *) context; struct kcopyd_job *job = sub_job->master_job; struct dm_kcopyd_client *kc = job->kc; + unsigned long flags; - spin_lock(>lock); + spin_lock_irqsave(>lock, flags); /* update the error */ if (read_err) @@ -653,7 +652,7 @@ static void segment_complete(int read_er job->progress += count; } } - spin_unlock(>lock); + spin_unlock_irqrestore(>lock, flags); if (count) { int i; @@ -714,29 +713,25 @@ static void submit_job(struct kcopyd_job } } -static void copy_offload_work(struct work_struct *work) +static void copy_offload_callback(void *ptr, int error) { - struct kcopyd_job *job = container_of(work, struct kcopyd_job, copy_work); - sector_t copied; + struct kcopyd_job *job = ptr; - blkdev_issue_copy(job->source.bdev, job->source.sector, - job->dests[0].bdev, job->dests[0].sector, - job->source.count, - GFP_NOIO | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN, - NULL, NULL, ); - - job->source.sector += copied; - job->source.count -= copied; - job->dests[0].sector += copied; - job->dests[0].count -= copied; + job->source.sector += job->progress; + job->source.count -= job->progress; + job->dests[0].sector += job->progress; + job->dests[0].count -= job->progress; submit_job(job); } static void try_copy_offload(struct kcopyd_job *job) { - INIT_WORK(>copy_work, copy_offload_work); - queue_work(job->kc->kcopyd_wq, >copy_work); + blkdev_issue_copy(job->source.bdev, job->source.sector, + job->dests[0].bdev, job->dests[0].sector, + job->source.count, + GFP_NOIO | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN, + copy_offload_callback, job, >progress); } int dm_kcopyd_copy(struct dm_kcopyd_client *kc, struct dm_io_region *from, -- 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: [BISECTED] WARNING: CPU: 2 PID: 142 at block/genhd.c:626 add_disk+0x480/0x4e0()
On 12/09/2015 10:52 PM, Hannes Reinecke wrote: There's a patchset to update the ALUA handler in Martin Petersens tree which should help here; most notably the commit 'scsi: ignore errors from scsi_dh_add_device()' should fix this particular issue. Yep, that fixed it. Thanks. Cheers, 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
Re: [PATCH] [SCSI] osd: fix signed char versus %02x issue
On Thu, Dec 10, 2015 at 8:15 PM, Martin K. Petersenwrote: >> "Rasmus" == Rasmus Villemoes writes: > > Rasmus> If char is signed and one of these bytes happen to have a value > Rasmus> outside the ascii range, the corresponding output will consist > Rasmus> of "ff" followed by the two hex chars that were actually > Rasmus> intended. One way to fix it would be to change the casts to > Rasmus> (u8*) aka (unsigned char*), but it is much simpler (and > Rasmus> generates smaller code) to use the %ph extension which was > Rasmus> created for such short hexdumps. > > Applied to 4.5/scsi-queue. How fast! Martin, I have several patches on SCSI subsytem like this one. Some of them didn't manage kernel (even having Ack!) for years already. Is it okay if I collect them together and send a bunch once again Cc'ing you? -- With Best Regards, Andy Shevchenko -- 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] osd: fix signed char versus %02x issue
> "Andy" == Andy Shevchenkowrites: Andy> I have several patches on SCSI subsytem like this one. Some of Andy> them didn't manage kernel (even having Ack!) for years already. Andy> Is it okay if I collect them together and send a bunch once again Re-sending to linux-scsi is fine. The trick is finding people willing to review them... -- Martin K. Petersen Oracle Linux Engineering -- 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] osd: fix signed char versus %02x issue
On Thu, 2015-12-10 at 14:13 -0500, Martin K. Petersen wrote: > > > > > > "Andy" == Andy Shevchenkowrites: > > Andy> I have several patches on SCSI subsytem like this one. Some of > Andy> them didn't manage kernel (even having Ack!) for years already. > Andy> Is it okay if I collect them together and send a bunch once again > > Re-sending to linux-scsi is fine. The trick is finding people willing to > review them... Generally speaking, it hasn't been for lack of review. SCSI has been one of the slowest subsystems to apply simple defect correction (not whitespace style) patches. Mostly these patches have been ignored. -- 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] hisi_sas: use platform_get_irq()
On Thu, Dec 10, 2015 at 9:02 AM, John Garrywrote: > It is preferred that drivers use platform_get_irq() > instead of irq_of_parse_and_map(), so replace. You may be able to stop including of_irq.h with this change. Otherwise, Acked-by: Rob Herring > > Signed-off-by: John Garry > > diff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c > b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c > index 89ae31d..e907758 100644 > --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c > +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c > @@ -1673,19 +1673,16 @@ static irq_handler_t > fatal_interrupts[HISI_SAS_MAX_QUEUES] = { > > static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) > { > - struct device *dev = _hba->pdev->dev; > - struct device_node *np = dev->of_node; > + struct platform_device *pdev = hisi_hba->pdev; > + struct device *dev = >dev; > int i, j, irq, rc, idx; > > - if (!np) > - return -ENOENT; > - > for (i = 0; i < hisi_hba->n_phy; i++) { > struct hisi_sas_phy *phy = _hba->phy[i]; > > idx = i * HISI_SAS_PHY_INT_NR; > for (j = 0; j < HISI_SAS_PHY_INT_NR; j++, idx++) { > - irq = irq_of_parse_and_map(np, idx); > + irq = platform_get_irq(pdev, idx); > if (!irq) { > dev_err(dev, > "irq init: fail map phy interrupt > %d\n", > @@ -1706,7 +1703,7 @@ static int interrupt_init_v1_hw(struct hisi_hba > *hisi_hba) > > idx = hisi_hba->n_phy * HISI_SAS_PHY_INT_NR; > for (i = 0; i < hisi_hba->queue_count; i++, idx++) { > - irq = irq_of_parse_and_map(np, idx); > + irq = platform_get_irq(pdev, idx); > if (!irq) { > dev_err(dev, "irq init: could not map cq interrupt > %d\n", > idx); > @@ -1724,7 +1721,7 @@ static int interrupt_init_v1_hw(struct hisi_hba > *hisi_hba) > > idx = (hisi_hba->n_phy * HISI_SAS_PHY_INT_NR) + hisi_hba->queue_count; > for (i = 0; i < HISI_SAS_FATAL_INT_NR; i++, idx++) { > - irq = irq_of_parse_and_map(np, idx); > + irq = platform_get_irq(pdev, idx); > if (!irq) { > dev_err(dev, "irq init: could not map fatal interrupt > %d\n", > idx); > -- > 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 RESEND] cxlflash: a couple off by one bugs
> "Matthew" == Matthew R Ochswrites: Matthew> The "> MAX_CONTEXT" should be ">= MAX_CONTEXT". Otherwise we Matthew> go one step beyond the end of the cfg->ctx_tbl[] array. Applied to 4.5/scsi-queue. -- Martin K. Petersen Oracle Linux Engineering -- 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 08/13] IB/srpt: chain RDMA READ/WRITE requests
On 12/07/2015 12:51 PM, Christoph Hellwig wrote: Remove struct rdma_iu and instead allocate the struct ib_rdma_wr array early and fill out directly. This allows us to chain the WRs, and thus archive both less lock contention on the HCA workqueue as well as much ^^^ Did you perhaps intend "achieve" ? struct srpt_send_ioctx { struct srpt_ioctx ioctx; struct srpt_rdma_ch *ch; - struct rdma_iu *rdma_ius; + struct ib_rdma_wr *rdma_ius; Please rename the "rdma_ius" member into "wr" or any other name that shows that this member is now a work request array and nothing else. Otherwise this patch looks fine to me. 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 0/15] copy offload patches
> "Mikulas" == Mikulas Patockawrites: Mikulas, Mikulas> This patch series adds copy offload (the XCOPY command) to the Mikulas> block layer, SCSI subsystems and device mapper. Now that the VFS stuff appears to stabilize I agree it's a good time to revisit all this. I just merged the required VPD patches from Hannes so those will be in 4.5. I have a bunch of changes to the SCSI code that I worked on over the spring/summer based on a feedback from the array vendors after discussions we started at LSF/MM. Generally speaking, their comments didn't make things easier, nor prettier :( But your two bio approach is a requirement to accommodate those needs (token-based copy) so I'll work on consolidating your changes with mine. That said, we still need Mike Christie's patches to go in first. Mike: What's your status? I'm afraid I didn't get a chance to dig very deep in your series since it coincided with me scrambling to sort out SCSI for 4.4. Do you think there's a chance we could get your patches in shape for 4.5? Is there an up-to-date tree I can look at? -- Martin K. Petersen Oracle Linux Engineering -- 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: [PATCHv4 1/1] SCSI: hosts: update to use ida_simple for host_no management
On 11/17/2015 03:20 PM, Martin K. Petersen wrote: >> "Lee" == Lee Duncanwrites: > > Lee> Martin: I will be glad to update the patch, creating a modprobe > Lee> parameter as suggested, if you find this acceptable. > > For development use a module parameter would be fine. But I am concerned > about our support folks that rely on the incrementing host number when > analyzing customer log files. > > Ewan: How do you folks feel about this change? > Ewan? -- Lee Duncan -- 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 0/4] scsi: storvsc: Properly support FC hosts
Properly support FC hosts. Additional cleanup patches are also included. K. Y. Srinivasan (4): scsi: storvsc: Fix a bug in the layout of the hv_fc_wwn_packet scsi: storvsc: Properly support Fibre Channel devices scsi: storvsc: Refactor the code in storvsc_channel_init() scsi: storvsc: Tighten up the interrupt path drivers/scsi/storvsc_drv.c | 235 ++-- 1 files changed, 138 insertions(+), 97 deletions(-) -- 1.7.4.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 1/4] scsi: storvsc: Fix a bug in the layout of the hv_fc_wwn_packet
The hv_fc_wwn_packet is exchanged over vmbus. Make the definition in Linux match the Window's definition. Signed-off-by: K. Y. SrinivasanReviewed-by: Long Li Tested-by: Alex Ng --- drivers/scsi/storvsc_drv.c |5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index c41f674..00bb4bd 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -92,9 +92,8 @@ enum vstor_packet_operation { */ struct hv_fc_wwn_packet { - boolprimary_active; - u8 reserved1; - u8 reserved2; + u8 primary_active; + u8 reserved1[3]; u8 primary_port_wwn[8]; u8 primary_node_wwn[8]; u8 secondary_port_wwn[8]; -- 1.7.4.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 0/6] cxlflash: Miscellaneous fixes and updates
This patch set contains miscellaneous fixes and adds support for a future IBM CXL adapter. This series is intended for 4.5 and is bisectable. Manoj Kumar (4): cxlflash: Fix to escalate LINK_RESET also on port 1 cxlflash: Fix to resolve cmd leak after host reset cxlflash: Resolve oops in wait_port_offline cxlflash: Enable device id for future IBM CXL adapter Matthew R. Ochs (1): cxlflash: Fix to avoid virtual LUN failover failure Uma Krishnan (1): cxlflash: Updated date of the driver drivers/scsi/cxlflash/common.h | 2 ++ drivers/scsi/cxlflash/main.c | 51 +- drivers/scsi/cxlflash/main.h | 6 ++--- drivers/scsi/cxlflash/vlun.c | 2 ++ include/uapi/scsi/cxlflash_ioctl.h | 10 5 files changed, 62 insertions(+), 9 deletions(-) -- 2.1.0 -- 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 74/71] ncr5380: Enable PDMA for NCR53C400A
On Wed, 9 Dec 2015, Ondrej Zary wrote: > On Tuesday 08 December 2015 03:05:11 Finn Thain wrote: > > > > On Sun, 6 Dec 2015, Ondrej Zary wrote: > > > > > Add I/O register mapping for NCR53C400A and enable PDMA mode to > > > improve performance and fix non-working IRQ. > > > > > > Tested with HP C2502 (and user-space enabler). > > > > > > Signed-off-by: Ondrej Zary> > > --- > > > drivers/scsi/g_NCR5380.c | 14 +++--- > > > 1 file changed, 11 insertions(+), 3 deletions(-) > > > > > > diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c > > > index 86740fd..099fdac 100644 > > > --- a/drivers/scsi/g_NCR5380.c > > > +++ b/drivers/scsi/g_NCR5380.c > > > @@ -324,7 +324,7 @@ static int __init generic_NCR5380_detect(struct > > > scsi_host_template *tpnt) > > > #endif > > > break; > > > case BOARD_NCR53C400A: > > > - flags = FLAG_NO_PSEUDO_DMA; > > > + flags = FLAG_NO_DMA_FIXUP; > > > ports = ncr_53c400a_ports; > > > break; > > > case BOARD_DTC3181E: > > > @@ -406,11 +406,18 @@ static int __init generic_NCR5380_detect(struct > > > scsi_host_template *tpnt) > > >* On NCR53C400 boards, NCR5380 registers are mapped 8 past > > >* the base address. > > >*/ > > > - if (overrides[current_override].board == BOARD_NCR53C400) { > > > + switch (overrides[current_override].board) { > > > + case BOARD_NCR53C400: > > > instance->io_port += 8; > > > hostdata->c400_ctl_status = 0; > > > hostdata->c400_blk_cnt = 1; > > > hostdata->c400_host_buf = 4; > > > + break; > > > + case BOARD_NCR53C400A: > > > + hostdata->c400_ctl_status = 9; > > > + hostdata->c400_blk_cnt = 10; > > > + hostdata->c400_host_buf = 8; > > > + break; > > > } > > > #else > > > instance->base = overrides[current_override].NCR5380_map_name; > > > > > > For SCSI_G_NCR5380_MEM and BOARD_NCR53C400A (or BOARD_DTC3181E), you have > > not assigned c400_ctl_status, c400_blk_cnt and c400_host_buf. Perhaps we > > should throw an error, something like this? > > > > hostdata->iomem = iomem; > > - if (overrides[current_override].board == BOARD_NCR53C400) { > > + switch (overrides[current_override].board) { > > + case BOARD_NCR53C400: > > hostdata->c400_ctl_status = 0x100; > > hostdata->c400_blk_cnt = 0x101; > > hostdata->c400_host_buf = 0x104; > > + break; > > + case BOARD_NCR53C400A: > > + pr_err(DRV_MODULE_NAME ": unknown register offsets\n"); > > + goto out_unregister; > > } > > #endif > > We don't need to fail, just disable PDMA by setting: > flags = FLAG_NO_PSEUDO_DMA; > > And BTW. this: > if (overrides[current_override].board == BOARD_NCR53C400 || > overrides[current_override].board == BOARD_NCR53C400A) > NCR5380_write(hostdata->c400_ctl_status, CSR_BASE); > > should then be, solving the problem of growing if condition: > if (!(flags & FLAG_NO_PSEUDO_DMA)) > NCR5380_write(hostdata->c400_ctl_status, CSR_BASE); > We already resolved that problem. Julian Calaby and I agreed that a switch statement is better than a flag here. Moreover, if the user sets the 'ncr_53c400' or 'ncr_53c400a' module options I presume they expect corresponding device initialization. I don't think PIO means we should skip that. Passing 'ncr_53c400' or 'ncr_53c400a' options to the g_NCR5380_mmio module has to give an error if we don't have enough information about the board to allow us to do the right thing. (Passing the 'ncr_5380' module param may give the result you wanted.) BTW, I fixed up this patch when I added it to my queue. I'll send you my version to test. 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
[PATCH 4/6] cxlflash: Fix to resolve cmd leak after host reset
From: Manoj KumarAfter a few iterations of resetting the card, either during EEH recovery, or a host_reset the following is seen in the logs. cxlflash 0008:00: cxlflash_queuecommand: could not get a free command At every reset of the card, the commands that are outstanding are being leaked. No effort is being made to reap these commands. A few more resets later, the above error message floods the logs and the card is rendered totally unusable as no free commands are available. Iterated through the 'cmd' queue and printed out the 'free' counter and found that on each reset certain commands were in-use and stayed in-use through subsequent resets. To resolve this issue, when the card is reset, reap all the commands that are active/outstanding. Signed-off-by: Manoj N. Kumar --- drivers/scsi/cxlflash/main.c | 19 +-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c index 09fe252..5d1d627 100644 --- a/drivers/scsi/cxlflash/main.c +++ b/drivers/scsi/cxlflash/main.c @@ -632,15 +632,30 @@ static void free_mem(struct cxlflash_cfg *cfg) * @cfg: Internal structure associated with the host. * * Safe to call with AFU in a partially allocated/initialized state. + * + * Cleans up all state associated with the command queue, and unmaps + * the MMIO space. + * + * - complete() will take care of commands we initiated (they'll be checked + * in as part of the cleanup that occurs after the completion) + * + * - cmd_checkin() will take care of entries that we did not initiate and that + * have not (and will not) complete because they are sitting on a [now stale] + * hardware queue */ static void stop_afu(struct cxlflash_cfg *cfg) { int i; struct afu *afu = cfg->afu; + struct afu_cmd *cmd; if (likely(afu)) { - for (i = 0; i < CXLFLASH_NUM_CMDS; i++) - complete(>cmd[i].cevent); + for (i = 0; i < CXLFLASH_NUM_CMDS; i++) { + cmd = >cmd[i]; + complete(>cevent); + if (!atomic_read(>free)) + cmd_checkin(cmd); + } if (likely(afu->afu_map)) { cxl_psa_unmap((void __iomem *)afu->afu_map); -- 2.1.0 -- 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 5/6] cxlflash: Resolve oops in wait_port_offline
From: Manoj KumarIf an async error interrupt is generated, and the error requires the FC link to be reset, it cannot be performed in the interrupt context. So a work element is scheduled to complete the link reset in a process context. If either an EEH event or an escalation occurs in between when the interrupt is generated and the scheduled work is started, the MMIO space may no longer be available. This will cause an oops in the worker thread. [ 606.806583] NIP kthread_data+0x28/0x40 [ 606.806633] LR wq_worker_sleeping+0x30/0x100 [ 606.806694] Call Trace: [ 606.806721] 0x50 (unreliable) [ 606.806796] wq_worker_sleeping+0x30/0x100 [ 606.806884] __schedule+0x69c/0x8a0 [ 606.806959] schedule+0x44/0xc0 [ 606.807034] do_exit+0x770/0xb90 [ 606.807109] die+0x300/0x460 [ 606.807185] bad_page_fault+0xd8/0x150 [ 606.807259] handle_page_fault+0x2c/0x30 [ 606.807338] wait_port_offline.constprop.12+0x60/0x130 [cxlflash] To prevent the problem space area from being unmapped, when there is pending work, a mapcount (using the kref mechanism) is held. The mapcount is released only when the work is completed. The last reference release is tied to the unmapping service. Signed-off-by: Manoj N. Kumar --- drivers/scsi/cxlflash/common.h | 2 ++ drivers/scsi/cxlflash/main.c | 27 --- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/cxlflash/common.h b/drivers/scsi/cxlflash/common.h index c11cd19..5ada926 100644 --- a/drivers/scsi/cxlflash/common.h +++ b/drivers/scsi/cxlflash/common.h @@ -165,6 +165,8 @@ struct afu { struct sisl_host_map __iomem *host_map; /* MC host map */ struct sisl_ctrl_map __iomem *ctrl_map; /* MC control map */ + struct kref mapcount; + ctx_hndl_t ctx_hndl;/* master's context handle */ u64 *hrrq_start; u64 *hrrq_end; diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c index 5d1d627..021b526 100644 --- a/drivers/scsi/cxlflash/main.c +++ b/drivers/scsi/cxlflash/main.c @@ -368,6 +368,7 @@ out: no_room: afu->read_room = true; + kref_get(>afu->mapcount); schedule_work(>work_q); rc = SCSI_MLQUEUE_HOST_BUSY; goto out; @@ -473,6 +474,16 @@ out: return rc; } +static void afu_unmap(struct kref *ref) +{ + struct afu *afu = container_of(ref, struct afu, mapcount); + + if (likely(afu->afu_map)) { + cxl_psa_unmap((void __iomem *)afu->afu_map); + afu->afu_map = NULL; + } +} + /** * cxlflash_driver_info() - information handler for this host driver * @host: SCSI host associated with device. @@ -503,6 +514,7 @@ static int cxlflash_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scp) ulong lock_flags; short lflag = 0; int rc = 0; + int kref_got = 0; dev_dbg_ratelimited(dev, "%s: (scp=%p) %d/%d/%d/%llu " "cdb=(%08X-%08X-%08X-%08X)\n", @@ -547,6 +559,9 @@ static int cxlflash_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scp) goto out; } + kref_get(>afu->mapcount); + kref_got = 1; + cmd->rcb.ctx_id = afu->ctx_hndl; cmd->rcb.port_sel = port_sel; cmd->rcb.lun_id = lun_to_lunid(scp->device->lun); @@ -587,6 +602,8 @@ static int cxlflash_queuecommand(struct Scsi_Host *host, struct scsi_cmnd *scp) } out: + if (kref_got) + kref_put(>mapcount, afu_unmap); pr_devel("%s: returning rc=%d\n", __func__, rc); return rc; } @@ -661,6 +678,7 @@ static void stop_afu(struct cxlflash_cfg *cfg) cxl_psa_unmap((void __iomem *)afu->afu_map); afu->afu_map = NULL; } + kref_put(>mapcount, afu_unmap); } } @@ -746,8 +764,8 @@ static void cxlflash_remove(struct pci_dev *pdev) scsi_remove_host(cfg->host); /* fall through */ case INIT_STATE_AFU: - term_afu(cfg); cancel_work_sync(>work_q); + term_afu(cfg); case INIT_STATE_PCI: pci_release_regions(cfg->dev); pci_disable_device(pdev); @@ -1331,6 +1349,7 @@ static irqreturn_t cxlflash_async_err_irq(int irq, void *data) __func__, port); cfg->lr_state = LINK_RESET_REQUIRED; cfg->lr_port = port; + kref_get(>afu->mapcount); schedule_work(>work_q); } @@ -1351,6 +1370,7 @@ static irqreturn_t cxlflash_async_err_irq(int irq, void *data) if (info->action & SCAN_HOST) { atomic_inc(>scan_host_needed); + kref_get(>afu->mapcount); schedule_work(>work_q); }
[PATCH 3/6] cxlflash: Updated date of the driver
This change is to update the date when last change was made to the cxlflash driver Signed-off-by: Uma Krishnan--- drivers/scsi/cxlflash/main.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/cxlflash/main.h b/drivers/scsi/cxlflash/main.h index 6032456..ddc4a97 100644 --- a/drivers/scsi/cxlflash/main.h +++ b/drivers/scsi/cxlflash/main.h @@ -22,7 +22,7 @@ #define CXLFLASH_NAME "cxlflash" #define CXLFLASH_ADAPTER_NAME "IBM POWER CXL Flash Adapter" -#define CXLFLASH_DRIVER_DATE "(August 13, 2015)" +#define CXLFLASH_DRIVER_DATE "(October 26, 2015)" #define PCI_DEVICE_ID_IBM_CORSA0x04F0 #define CXLFLASH_SUBS_DEV_ID 0x04F0 -- 2.1.0 -- 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 1/6] cxlflash: Fix to escalate LINK_RESET also on port 1
From: Manoj KumarThe original fix to escalate a 'login timed out' error to a LINK_RESET was only made for one of the two ports on the card. This fix resolves the same issue for the second port (port 1). Signed-off-by: Manoj N. Kumar --- drivers/scsi/cxlflash/main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c index 1e5bf0c..09fe252 100644 --- a/drivers/scsi/cxlflash/main.c +++ b/drivers/scsi/cxlflash/main.c @@ -1108,7 +1108,7 @@ static const struct asyc_intr_info ainfo[] = { {SISL_ASTATUS_FC1_OTHER, "other error", 1, CLR_FC_ERROR | LINK_RESET}, {SISL_ASTATUS_FC1_LOGO, "target initiated LOGO", 1, 0}, {SISL_ASTATUS_FC1_CRC_T, "CRC threshold exceeded", 1, LINK_RESET}, - {SISL_ASTATUS_FC1_LOGI_R, "login timed out, retrying", 1, 0}, + {SISL_ASTATUS_FC1_LOGI_R, "login timed out, retrying", 1, LINK_RESET}, {SISL_ASTATUS_FC1_LOGI_F, "login failed", 1, CLR_FC_ERROR}, {SISL_ASTATUS_FC1_LOGI_S, "login succeeded", 1, SCAN_HOST}, {SISL_ASTATUS_FC1_LINK_DN, "link down", 1, 0}, -- 2.1.0 -- 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 2/6] cxlflash: Fix to avoid virtual LUN failover failure
From: "Matthew R. Ochs"Applications which use virtual LUN's that are backed by a physical LUN over both adapter ports may experience an I/O failure in the event of a link loss (e.g. cable pull). Virtual LUNs may be accessed through one or both ports of the adapter. This access is encoded in the translation entries that comprise the virtual LUN and used by the AFU for load-balancing I/O and handling failover scenarios. In a link loss scenario, even though the AFU is able to maintain connectivity to the LUN, it is up to the application to retry the failed I/O. When applications are unaware of the virtual LUN's underlying topology, they are unable to make a sound decision of when to retry an I/O and therefore are forced to make their reaction to a failed I/O absolute. The result is either a failure to retry I/O or increased latency for scenarios where a retry is pointless. To remedy this scenario, provide feedback back to the application on virtual LUN creation as to which ports the LUN may be accessed. LUN's spanning both ports are candidates for a retry in a presence of an I/O failure. Signed-off-by: Matthew R. Ochs --- drivers/scsi/cxlflash/vlun.c | 2 ++ include/uapi/scsi/cxlflash_ioctl.h | 10 ++ 2 files changed, 12 insertions(+) diff --git a/drivers/scsi/cxlflash/vlun.c b/drivers/scsi/cxlflash/vlun.c index a53f583..50f8e93 100644 --- a/drivers/scsi/cxlflash/vlun.c +++ b/drivers/scsi/cxlflash/vlun.c @@ -1008,6 +1008,8 @@ int cxlflash_disk_virtual_open(struct scsi_device *sdev, void *arg) virt->last_lba = last_lba; virt->rsrc_handle = rsrc_handle; + if (lli->port_sel == BOTH_PORTS) + virt->hdr.return_flags |= DK_CXLFLASH_ALL_PORTS_ACTIVE; out: if (likely(ctxi)) put_context(ctxi); diff --git a/include/uapi/scsi/cxlflash_ioctl.h b/include/uapi/scsi/cxlflash_ioctl.h index 831351b..2302f3c 100644 --- a/include/uapi/scsi/cxlflash_ioctl.h +++ b/include/uapi/scsi/cxlflash_ioctl.h @@ -31,6 +31,16 @@ struct dk_cxlflash_hdr { }; /* + * Return flag definitions available to all ioctls + * + * Similar to the input flags, these are grown from the bottom-up with the + * intention that ioctl-specific return flag definitions would grow from the + * top-down, allowing the two sets to co-exist. While not required/enforced + * at this time, this provides future flexibility. + */ +#define DK_CXLFLASH_ALL_PORTS_ACTIVE 0x0001ULL + +/* * Notes: * - * The 'context_id' field of all ioctl structures contains the context -- 2.1.0 -- 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 78/71] ncr5380: Add support for HP 53C400A-based cards (C2502)
On Wed, 9 Dec 2015, Ondrej Zary wrote: > > > @@ -743,6 +786,7 @@ module_param(ncr_5380, int, 0); > > > module_param(ncr_53c400, int, 0); > > > module_param(ncr_53c400a, int, 0); > > > module_param(dtc_3181e, int, 0); > > > +module_param(hp_53c400a, int, 0); > > > > Any reason you did not add the corresponding __setup option? > > I wonder if __setup is really required. I thought that it should go away > and module parameters used instead. Yes, after re-reading the header files I see that you are right. > > > Did you consider re-using the existing ncr_53c400a option (for port & > > irq settings) and adding a new setup option and module param for card > > magic? > > Looks like a good idea. What I had in mind was an 'ncr_magic' option, to go with 'ncr_irq' and 'ncr_addr'. This is supposed to be a generic driver, after all. But now that I've seen what that would involve (adding another member to struct override) I've changed my mind. I think the new board type was the right approach. That is, a combination of your v2 and v3 patches. I'll send my version to you to test. 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
[PATCH 2/4] scsi: storvsc: Properly support Fibre Channel devices
For FC devices managed by this driver, atttach the appropriate transport template. This will allow us to create the appropriate sysfs files for these devices. With this we can publish the wwn for both the port and the node. Signed-off-by: K. Y. SrinivasanReviewed-by: Long Li Tested-by: Alex Ng --- drivers/scsi/storvsc_drv.c | 100 +-- 1 files changed, 95 insertions(+), 5 deletions(-) diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 00bb4bd..b94d471 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -41,6 +41,7 @@ #include #include #include +#include /* * All wire protocol details (storage protocol between the guest and the host) @@ -397,6 +398,7 @@ static int storvsc_timeout = 180; static int msft_blist_flags = BLIST_TRY_VPD_PAGES; +static struct scsi_transport_template *fc_transport_template; static void storvsc_on_channel_callback(void *context); @@ -456,6 +458,11 @@ struct storvsc_device { /* Used for vsc/vsp channel reset process */ struct storvsc_cmd_request init_request; struct storvsc_cmd_request reset_request; + /* +* Currently active port and node names for FC devices. +*/ + u64 node_name; + u64 port_name; }; struct hv_host_device { @@ -695,7 +702,26 @@ static void handle_multichannel_storage(struct hv_device *device, int max_chns) vmbus_are_subchannels_present(device->channel); } -static int storvsc_channel_init(struct hv_device *device) +static void cache_wwn(struct storvsc_device *stor_device, + struct vstor_packet *vstor_packet) +{ + /* +* Cache the currently active port and node ww names. +*/ + if (vstor_packet->wwn_packet.primary_active) { + stor_device->node_name = + wwn_to_u64(vstor_packet->wwn_packet.primary_node_wwn); + stor_device->port_name = + wwn_to_u64(vstor_packet->wwn_packet.primary_port_wwn); + } else { + stor_device->node_name = + wwn_to_u64(vstor_packet->wwn_packet.secondary_node_wwn); + stor_device->port_name = + wwn_to_u64(vstor_packet->wwn_packet.secondary_port_wwn); + } +} + +static int storvsc_channel_init(struct hv_device *device, bool is_fc) { struct storvsc_device *stor_device; struct storvsc_cmd_request *request; @@ -837,6 +863,40 @@ static int storvsc_channel_init(struct hv_device *device) stor_device->max_transfer_bytes = vstor_packet->storage_channel_properties.max_transfer_bytes; + if (!is_fc) + goto done; + + memset(vstor_packet, 0, sizeof(struct vstor_packet)); + vstor_packet->operation = VSTOR_OPERATION_FCHBA_DATA; + vstor_packet->flags = REQUEST_COMPLETION_FLAG; + + ret = vmbus_sendpacket(device->channel, vstor_packet, + (sizeof(struct vstor_packet) - + vmscsi_size_delta), + (unsigned long)request, + VM_PKT_DATA_INBAND, + VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); + + if (ret != 0) + goto cleanup; + + t = wait_for_completion_timeout(>wait_event, 5*HZ); + if (t == 0) { + ret = -ETIMEDOUT; + goto cleanup; + } + + if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || + vstor_packet->status != 0) + goto cleanup; + + /* +* Cache the currently active port and node ww names. +*/ + cache_wwn(stor_device, vstor_packet); + +done: + memset(vstor_packet, 0, sizeof(struct vstor_packet)); vstor_packet->operation = VSTOR_OPERATION_END_INITIALIZATION; vstor_packet->flags = REQUEST_COMPLETION_FLAG; @@ -1076,6 +1136,12 @@ static void storvsc_on_receive(struct hv_device *device, schedule_work(>work); break; + case VSTOR_OPERATION_FCHBA_DATA: + stor_device = get_in_stor_device(device); + cache_wwn(stor_device, vstor_packet); + fc_host_node_name(stor_device->host) = stor_device->node_name; + fc_host_port_name(stor_device->host) = stor_device->port_name; + break; default: break; } @@ -1131,7 +1197,8 @@ static void storvsc_on_channel_callback(void *context) return; } -static int storvsc_connect_to_vsp(struct hv_device *device, u32 ring_size) +static int storvsc_connect_to_vsp(struct hv_device *device, u32 ring_size, + bool is_fc) { struct vmstorage_channel_properties props; int ret; @@ -1148,7 +1215,7 @@ static int storvsc_connect_to_vsp(struct
[PATCH 4/4] scsi: storvsc: Tighten up the interrupt path
On the interrupt path, we repeatedly establish the pointer to the storvsc_device. Fix this. Signed-off-by: K. Y. SrinivasanReviewed-by: Long Li Tested-by: Alex Ng --- drivers/scsi/storvsc_drv.c | 23 --- 1 files changed, 8 insertions(+), 15 deletions(-) diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 6f18e94..8ba9908 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -958,19 +958,16 @@ static void storvsc_handle_error(struct vmscsi_request *vm_srb, } -static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request) +static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request, + struct storvsc_device *stor_dev) { struct scsi_cmnd *scmnd = cmd_request->cmd; - struct hv_host_device *host_dev = shost_priv(scmnd->device->host); struct scsi_sense_hdr sense_hdr; struct vmscsi_request *vm_srb; struct Scsi_Host *host; - struct storvsc_device *stor_dev; - struct hv_device *dev = host_dev->dev; u32 payload_sz = cmd_request->payload_sz; void *payload = cmd_request->payload; - stor_dev = get_in_stor_device(dev); host = stor_dev->host; vm_srb = _request->vstor_packet.vm_srb; @@ -1000,14 +997,13 @@ static void storvsc_command_completion(struct storvsc_cmd_request *cmd_request) kfree(payload); } -static void storvsc_on_io_completion(struct hv_device *device, +static void storvsc_on_io_completion(struct storvsc_device *stor_device, struct vstor_packet *vstor_packet, struct storvsc_cmd_request *request) { - struct storvsc_device *stor_device; struct vstor_packet *stor_pkt; + struct hv_device *device = stor_device->device; - stor_device = hv_get_drvdata(device); stor_pkt = >vstor_packet; /* @@ -1062,7 +1058,7 @@ static void storvsc_on_io_completion(struct hv_device *device, stor_pkt->vm_srb.data_transfer_length = vstor_packet->vm_srb.data_transfer_length; - storvsc_command_completion(request); + storvsc_command_completion(request, stor_device); if (atomic_dec_and_test(_device->num_outstanding_req) && stor_device->drain_notify) @@ -1071,21 +1067,19 @@ static void storvsc_on_io_completion(struct hv_device *device, } -static void storvsc_on_receive(struct hv_device *device, +static void storvsc_on_receive(struct storvsc_device *stor_device, struct vstor_packet *vstor_packet, struct storvsc_cmd_request *request) { struct storvsc_scan_work *work; - struct storvsc_device *stor_device; switch (vstor_packet->operation) { case VSTOR_OPERATION_COMPLETE_IO: - storvsc_on_io_completion(device, vstor_packet, request); + storvsc_on_io_completion(stor_device, vstor_packet, request); break; case VSTOR_OPERATION_REMOVE_DEVICE: case VSTOR_OPERATION_ENUMERATE_BUS: - stor_device = get_in_stor_device(device); work = kmalloc(sizeof(struct storvsc_scan_work), GFP_ATOMIC); if (!work) return; @@ -1096,7 +1090,6 @@ static void storvsc_on_receive(struct hv_device *device, break; case VSTOR_OPERATION_FCHBA_DATA: - stor_device = get_in_stor_device(device); cache_wwn(stor_device, vstor_packet); fc_host_node_name(stor_device->host) = stor_device->node_name; fc_host_port_name(stor_device->host) = stor_device->port_name; @@ -1144,7 +1137,7 @@ static void storvsc_on_channel_callback(void *context) vmscsi_size_delta)); complete(>wait_event); } else { - storvsc_on_receive(device, + storvsc_on_receive(stor_device, (struct vstor_packet *)packet, request); } -- 1.7.4.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 3/6] cxlflash: Updated date of the driver
Hi Uma, It looks like CXLFLASH_DRIVER_DATE is only used once, on init, and it's just printed. Is it necessary? It looks like having it will require sending a patch to update it quite often. Regards, Daniel signature.asc Description: PGP signature
[PATCH 3/4] scsi: storvsc: Refactor the code in storvsc_channel_init()
The function storvsc_channel_init() repeatedly interacts with the host to extract various channel properties. Refactor this code to eliminate code repetition. Signed-off-by: K. Y. SrinivasanReviewed-by: Long Li Tested-by: Alex Ng --- drivers/scsi/storvsc_drv.c | 155 1 files changed, 57 insertions(+), 98 deletions(-) diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index b94d471..6f18e94 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -721,29 +721,16 @@ static void cache_wwn(struct storvsc_device *stor_device, } } -static int storvsc_channel_init(struct hv_device *device, bool is_fc) +static int storvsc_execute_vstor_op(struct hv_device *device, + struct storvsc_cmd_request *request, + bool status_check) { - struct storvsc_device *stor_device; - struct storvsc_cmd_request *request; struct vstor_packet *vstor_packet; - int ret, t, i; - int max_chns; - bool process_sub_channels = false; - - stor_device = get_out_stor_device(device); - if (!stor_device) - return -ENODEV; + int ret, t; - request = _device->init_request; vstor_packet = >vstor_packet; - /* -* Now, initiate the vsc/vsp initialization protocol on the open -* channel -*/ - memset(request, 0, sizeof(struct storvsc_cmd_request)); init_completion(>wait_event); - vstor_packet->operation = VSTOR_OPERATION_BEGIN_INITIALIZATION; vstor_packet->flags = REQUEST_COMPLETION_FLAG; ret = vmbus_sendpacket(device->channel, vstor_packet, @@ -753,27 +740,62 @@ static int storvsc_channel_init(struct hv_device *device, bool is_fc) VM_PKT_DATA_INBAND, VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); if (ret != 0) - goto cleanup; + goto done; t = wait_for_completion_timeout(>wait_event, 5*HZ); if (t == 0) { ret = -ETIMEDOUT; - goto cleanup; + goto done; } + if (!status_check) + goto done; + if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO || vstor_packet->status != 0) { ret = -EINVAL; - goto cleanup; + goto done; } +done: + return ret; +} + +static int storvsc_channel_init(struct hv_device *device, bool is_fc) +{ + struct storvsc_device *stor_device; + struct storvsc_cmd_request *request; + struct vstor_packet *vstor_packet; + int ret, i; + int max_chns; + bool process_sub_channels = false; + + stor_device = get_out_stor_device(device); + if (!stor_device) + return -ENODEV; + + request = _device->init_request; + vstor_packet = >vstor_packet; + + /* +* Now, initiate the vsc/vsp initialization protocol on the open +* channel +*/ + memset(request, 0, sizeof(struct storvsc_cmd_request)); + vstor_packet->operation = VSTOR_OPERATION_BEGIN_INITIALIZATION; + ret = storvsc_execute_vstor_op(device, request, true); + if (ret) + goto cleanup; + + /* +* Query host supported protocol version. +*/ for (i = 0; i < ARRAY_SIZE(vmstor_protocols); i++) { /* reuse the packet for version range supported */ memset(vstor_packet, 0, sizeof(struct vstor_packet)); vstor_packet->operation = VSTOR_OPERATION_QUERY_PROTOCOL_VERSION; - vstor_packet->flags = REQUEST_COMPLETION_FLAG; vstor_packet->version.major_minor = vmstor_protocols[i].protocol_version; @@ -783,20 +805,9 @@ static int storvsc_channel_init(struct hv_device *device, bool is_fc) */ vstor_packet->version.revision = 0; - ret = vmbus_sendpacket(device->channel, vstor_packet, - (sizeof(struct vstor_packet) - - vmscsi_size_delta), - (unsigned long)request, - VM_PKT_DATA_INBAND, - VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED); - if (ret != 0) - goto cleanup; - - t = wait_for_completion_timeout(>wait_event, 5*HZ); - if (t == 0) { - ret = -ETIMEDOUT; + ret = storvsc_execute_vstor_op(device, request, false); + if (ret) goto cleanup; - } if (vstor_packet->operation != VSTOR_OPERATION_COMPLETE_IO) { ret
[PATCH 6/6] cxlflash: Enable device id for future IBM CXL adapter
From: Manoj KumarThis drop enables a future card with a device id of 0x0600 to be recognized by the cxlflash driver. No card specific programming has been added. These card specific changes will be staged in later. Signed-off-by: Manoj N. Kumar --- drivers/scsi/cxlflash/main.c | 3 +++ drivers/scsi/cxlflash/main.h | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/cxlflash/main.c b/drivers/scsi/cxlflash/main.c index 021b526..ec26b12 100644 --- a/drivers/scsi/cxlflash/main.c +++ b/drivers/scsi/cxlflash/main.c @@ -2309,6 +2309,7 @@ static struct scsi_host_template driver_template = { * Device dependent values */ static struct dev_dependent_vals dev_corsa_vals = { CXLFLASH_MAX_SECTORS }; +static struct dev_dependent_vals dev_flash_gt_vals = { CXLFLASH_MAX_SECTORS }; /* * PCI device binding table @@ -2316,6 +2317,8 @@ static struct dev_dependent_vals dev_corsa_vals = { CXLFLASH_MAX_SECTORS }; static struct pci_device_id cxlflash_pci_table[] = { {PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_CORSA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (kernel_ulong_t)_corsa_vals}, + {PCI_VENDOR_ID_IBM, PCI_DEVICE_ID_IBM_FLASH_GT, +PCI_ANY_ID, PCI_ANY_ID, 0, 0, (kernel_ulong_t)_flash_gt_vals}, {} }; diff --git a/drivers/scsi/cxlflash/main.h b/drivers/scsi/cxlflash/main.h index ddc4a97..5d2c7ae 100644 --- a/drivers/scsi/cxlflash/main.h +++ b/drivers/scsi/cxlflash/main.h @@ -24,8 +24,8 @@ #define CXLFLASH_ADAPTER_NAME "IBM POWER CXL Flash Adapter" #define CXLFLASH_DRIVER_DATE "(October 26, 2015)" -#define PCI_DEVICE_ID_IBM_CORSA0x04F0 -#define CXLFLASH_SUBS_DEV_ID 0x04F0 +#define PCI_DEVICE_ID_IBM_CORSA0x04F0 +#define PCI_DEVICE_ID_IBM_FLASH_GT 0x0600 /* Since there is only one target, make it 0 */ #define CXLFLASH_TARGET0 -- 2.1.0 -- 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 1/15] block copy: initial XCOPY offload support
This is Martin Petersen's xcopy patch (https://git.kernel.org/cgit/linux/kernel/git/mkp/linux.git/commit/?h=xcopy=0bdeed274e16b3038a851552188512071974eea8) with some bug fixes, ported to the current kernel. This patch makes it possible to use the SCSI XCOPY command. We create a bio that has REQ_COPY flag in bi_rw and a bi_copy structure that defines the source device. The target device is defined in the bi_bdev and bi_iter.bi_sector. There is a new BLKCOPY ioctl that makes it possible to use XCOPY from userspace. The ioctl argument is a pointer to an array of four uint64_t values. The first value is a source byte offset, the second value is a destination byte offset, the third value is byte length. The forth value is written by the kernel and it represents the number of bytes that the kernel actually copied. Signed-off-by: Martin K. PetersenSigned-off-by: Mikulas Patocka --- Documentation/ABI/testing/sysfs-block |9 + block/bio.c |2 block/blk-core.c |5 block/blk-lib.c | 95 +++ block/blk-merge.c | 11 - block/blk-settings.c | 13 + block/blk-sysfs.c | 11 + block/compat_ioctl.c |1 block/ioctl.c | 50 ++ drivers/scsi/scsi.c | 57 +++ drivers/scsi/sd.c | 271 +- drivers/scsi/sd.h |4 include/linux/bio.h |9 - include/linux/blk_types.h | 14 + include/linux/blkdev.h| 15 + include/scsi/scsi_device.h|3 include/uapi/linux/fs.h |1 17 files changed, 557 insertions(+), 14 deletions(-) Index: linux-4.4-rc4/Documentation/ABI/testing/sysfs-block === --- linux-4.4-rc4.orig/Documentation/ABI/testing/sysfs-block2015-12-10 17:03:59.0 +0100 +++ linux-4.4-rc4/Documentation/ABI/testing/sysfs-block 2015-12-10 17:04:30.0 +0100 @@ -235,3 +235,12 @@ Description: write_same_max_bytes is 0, write same is not supported by the device. + +What: /sys/block//queue/copy_max_bytes +Date: January 2014 +Contact: Martin K. Petersen +Description: + Devices that support copy offloading will set this value + to indicate the maximum buffer size in bytes that can be + copied in one operation. If the copy_max_bytes is 0 the + device does not support copy offload. Index: linux-4.4-rc4/block/blk-core.c === --- linux-4.4-rc4.orig/block/blk-core.c 2015-12-10 17:03:59.0 +0100 +++ linux-4.4-rc4/block/blk-core.c 2015-12-10 17:04:30.0 +0100 @@ -1957,6 +1957,11 @@ generic_make_request_checks(struct bio * goto end_io; } + if (bio->bi_rw & REQ_COPY && !bdev_copy_offload(bio->bi_bdev)) { + err = -EOPNOTSUPP; + goto end_io; + } + /* * Various block parts want %current->io_context and lazy ioc * allocation ends up trading a lot of pain for a small amount of Index: linux-4.4-rc4/block/blk-lib.c === --- linux-4.4-rc4.orig/block/blk-lib.c 2015-12-10 17:03:59.0 +0100 +++ linux-4.4-rc4/block/blk-lib.c 2015-12-10 17:04:30.0 +0100 @@ -299,3 +299,98 @@ int blkdev_issue_zeroout(struct block_de return __blkdev_issue_zeroout(bdev, sector, nr_sects, gfp_mask); } EXPORT_SYMBOL(blkdev_issue_zeroout); + +/** + * blkdev_issue_copy - queue a copy same operation + * @src_bdev: source blockdev + * @src_sector:source sector + * @dst_bdev: destination blockdev + * @dst_sector: destination sector + * @nr_sects: number of sectors to copy + * @gfp_mask: memory allocation flags (for bio_alloc) + * + * Description: + *Copy a block range from source device to target device. + */ +int blkdev_issue_copy(struct block_device *src_bdev, sector_t src_sector, + struct block_device *dst_bdev, sector_t dst_sector, + unsigned int nr_sects, gfp_t gfp_mask) +{ + DECLARE_COMPLETION_ONSTACK(wait); + struct request_queue *sq = bdev_get_queue(src_bdev); + struct request_queue *dq = bdev_get_queue(dst_bdev); + unsigned int max_copy_sectors; + struct bio_batch bb; + int ret = 0; + + if (!sq || !dq) + return -ENXIO; + + max_copy_sectors = min(sq->limits.max_copy_sectors, + dq->limits.max_copy_sectors); + + if (max_copy_sectors == 0) + return -EOPNOTSUPP; + + if (src_sector + nr_sects
Re: [PATCH 10/13] IB/srp: use the new CQ API
On 12/07/2015 12:51 PM, Christoph Hellwig wrote: +static void srp_send_done(struct ib_cq *cq, struct ib_wc *wc) +{ + struct srp_iu *iu = container_of(wc->wr_cqe, struct srp_iu, cqe); + struct srp_rdma_ch *ch = cq->cq_context; + + if (likely(wc->status != IB_WC_SUCCESS)) { + srp_handle_qp_err(cq, wc, "SEND"); + return; + } + + list_add(>list, >free_tx); +} Please change likely() in the above code into unlikely(). 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 03/13] irq_poll: fold irq_poll_sched_prep into irq_poll_sched
On 12/07/2015 12:51 PM, Christoph Hellwig wrote: @@ -58,7 +62,7 @@ EXPORT_SYMBOL(__irq_poll_complete); * Description: * If a driver consumes less than the assigned budget in its run of the * iopoll handler, it'll end the polled mode by calling this function. The - * iopoll handler will not be invoked again before irq_poll_sched_prep() + * iopoll handler will not be invoked again before irq_poll_schedp() * is called. **/ void irq_poll_complete(struct irq_poll *iop) Is that a typo at the end of the modified line ("schedp") ? If this gets addressed: Reviewed-by: Bart Van Assche-- 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 04/13] irq_poll: fold irq_poll_disable_pending into irq_poll_softirq
On 12/07/2015 12:51 PM, Christoph Hellwig wrote: > [ ... ] Reviewed-by: Bart Van Assche-- 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/15] dm linear: support copy
Support copy operation in the linear target. Signed-off-by: Mikulas Patocka--- drivers/md/dm-linear.c |1 + 1 file changed, 1 insertion(+) Index: linux-4.3-rc1/drivers/md/dm-linear.c === --- linux-4.3-rc1.orig/drivers/md/dm-linear.c 2015-09-14 16:06:36.0 +0200 +++ linux-4.3-rc1/drivers/md/dm-linear.c2015-09-14 16:22:44.0 +0200 @@ -59,6 +59,7 @@ static int linear_ctr(struct dm_target * ti->num_flush_bios = 1; ti->num_discard_bios = 1; ti->num_write_same_bios = 1; + ti->copy_supported = 1; ti->private = lc; return 0; -- 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 9/15] dm: implement copy
This patch implements basic copy support for device mapper core. Individual targets can enable copy support by setting ti->copy_supported. Device mapper device advertises copy support if at least one target supports copy and for this target, at least one underlying device supports copy. Signed-off-by: Mikulas Patocka--- drivers/md/dm-table.c | 16 drivers/md/dm.c | 27 +++ include/linux/device-mapper.h |5 + 3 files changed, 48 insertions(+) Index: linux-4.4-rc4/drivers/md/dm.c === --- linux-4.4-rc4.orig/drivers/md/dm.c 2015-12-10 17:04:05.0 +0100 +++ linux-4.4-rc4/drivers/md/dm.c 2015-12-10 17:05:48.0 +0100 @@ -1679,6 +1679,31 @@ static int __send_write_same(struct clon return __send_changing_extent_only(ci, get_num_write_same_bios, NULL); } +static int __send_copy(struct clone_info *ci) +{ + struct dm_target *ti; + sector_t bound; + + ti = dm_table_find_target(ci->map, ci->sector); + if (!dm_target_is_valid(ti)) + return -EIO; + + if (!ti->copy_supported) + return -EOPNOTSUPP; + + bound = max_io_len(ci->sector, ti); + + if (unlikely(ci->sector_count > bound)) + return -EOPNOTSUPP; + + __clone_and_map_simple_bio(ci, ti, 0, NULL); + + ci->sector += ci->sector_count; + ci->sector_count = 0; + + return 0; +} + /* * Select the correct strategy for processing a non-flush bio. */ @@ -1692,6 +1717,8 @@ static int __split_and_process_non_flush return __send_discard(ci); else if (unlikely(bio->bi_rw & REQ_WRITE_SAME)) return __send_write_same(ci); + else if (unlikely(bio->bi_rw & REQ_COPY)) + return __send_copy(ci); ti = dm_table_find_target(ci->map, ci->sector); if (!dm_target_is_valid(ti)) Index: linux-4.4-rc4/include/linux/device-mapper.h === --- linux-4.4-rc4.orig/include/linux/device-mapper.h2015-12-10 17:04:05.0 +0100 +++ linux-4.4-rc4/include/linux/device-mapper.h 2015-12-10 17:04:59.0 +0100 @@ -271,6 +271,11 @@ struct dm_target { * Set if this target does not return zeroes on discarded blocks. */ bool discard_zeroes_data_unsupported:1; + + /* +* Set if the target supports XCOPY. +*/ + bool copy_supported:1; }; /* Each target can link one of these into the table */ Index: linux-4.4-rc4/drivers/md/dm-table.c === --- linux-4.4-rc4.orig/drivers/md/dm-table.c2015-12-10 17:03:51.0 +0100 +++ linux-4.4-rc4/drivers/md/dm-table.c 2015-12-10 17:04:59.0 +0100 @@ -286,6 +286,11 @@ static int device_area_is_invalid(struct limits->logical_block_size >> SECTOR_SHIFT; char b[BDEVNAME_SIZE]; + if (ti->copy_supported) + limits->max_copy_sectors = + min_not_zero(limits->max_copy_sectors, + bdev_get_queue(bdev)->limits.max_copy_sectors); + /* * Some devices exist without request functions, * such as loop devices not yet bound to backing files. @@ -1256,6 +1261,13 @@ int dm_calculate_queue_limits(struct dm_ ti = dm_table_get_target(table, i++); + if (ti->begin) + ti_limits.copy_boundary = min(ti_limits.copy_boundary, + (unsigned char)__ffs64(ti->begin)); + if (ti->max_io_len) + ti_limits.copy_boundary = min(ti_limits.copy_boundary, + (unsigned char)__ffs(ti->max_io_len)); + if (!ti->type->iterate_devices) goto combine_limits; @@ -1289,6 +1301,10 @@ combine_limits: dm_device_name(table->md), (unsigned long long) ti->begin, (unsigned long long) ti->len); + + limits->max_copy_sectors = + min_not_zero(limits->max_copy_sectors, + ti_limits.max_copy_sectors); } return validate_hardware_logical_block_alignment(table, limits); -- 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 7/15] scsi xcopy: keep cache of failures
If xcopy between two devices fails, it is pointless to send more xcopy command between there two devices because they take time and they will likely also fail. This patch keeps a cache of (source_device,destination_device) pairs where copying failed and makes sure that no xcopy command is sooner than 30 seconds after the last failure. Signed-off-by: Mikulas Patocka--- drivers/scsi/sd.c | 37 + 1 file changed, 37 insertions(+) Index: linux-4.4-rc4/drivers/scsi/sd.c === --- linux-4.4-rc4.orig/drivers/scsi/sd.c2015-12-07 16:59:09.0 +0100 +++ linux-4.4-rc4/drivers/scsi/sd.c 2015-12-07 16:59:12.0 +0100 @@ -939,6 +939,26 @@ static void sd_config_copy(struct scsi_d (logical_block_size >> 9)); } +#define SD_COPY_DISABLED_CACHE_TIME(HZ * 30) +#define SD_COPY_DISABLED_CACHE_HASH_BITS 6 +#define SD_COPY_DISABLED_CACHE_HASH(1 << SD_COPY_DISABLED_CACHE_HASH_BITS) + +struct sd_copy_disabled_cache_entry { + struct scsi_device *src; + struct scsi_device *dst; + unsigned long jiffies; +}; + +static struct sd_copy_disabled_cache_entry sd_copy_disabled_cache[SD_COPY_DISABLED_CACHE_HASH]; + +static struct sd_copy_disabled_cache_entry *sd_copy_disabled_cache_hash( + struct scsi_device *src, struct scsi_device *dst) +{ + return _copy_disabled_cache[ + hash_long((unsigned long)src + ((unsigned long)dst >> 1), SD_COPY_DISABLED_CACHE_HASH_BITS) + ]; +} + static int sd_setup_copy_cmnd(struct scsi_cmnd *cmd) { struct request *rq = cmd->request; @@ -951,6 +971,7 @@ static int sd_setup_copy_cmnd(struct scs struct bio *bio = rq->bio; struct page *page; unsigned char *buf; + struct sd_copy_disabled_cache_entry *e; dst_sdp = scsi_disk(rq->rq_disk)->device; dst_queue = rq->rq_disk->queue; @@ -970,6 +991,12 @@ static int sd_setup_copy_cmnd(struct scs if (src_sdp->sector_size != dst_sdp->sector_size) return BLKPREP_KILL; + /* The copy failed in the past, so do not retry it for some time */ + e = sd_copy_disabled_cache_hash(src_sdp, dst_sdp); + if (unlikely(jiffies - ACCESS_ONCE(e->jiffies) < SD_COPY_DISABLED_CACHE_TIME) && + likely(ACCESS_ONCE(e->src) == src_sdp) && likely(ACCESS_ONCE(e->dst) == dst_sdp)) + return BLKPREP_KILL; + dst_lba = blk_rq_pos(rq) >> (ilog2(dst_sdp->sector_size) - 9); src_lba = bio->bi_copy->pair[0]->bi_iter.bi_sector >> (ilog2(src_sdp->sector_size) - 9); nr_blocks = blk_rq_sectors(rq) >> (ilog2(dst_sdp->sector_size) - 9); @@ -2003,6 +2030,16 @@ static int sd_done(struct scsi_cmnd *SCp */ case EXTENDED_COPY: if ((SCpnt->cmnd[1] & 0x1f) == 0) { + struct sd_copy_disabled_cache_entry *e; + struct scsi_device *src_sdp, *dst_sdp; + + dst_sdp = sdkp->device; + src_sdp = scsi_disk(req->bio->bi_copy->pair[0]->bi_bdev->bd_disk)->device; + e = sd_copy_disabled_cache_hash(src_sdp, dst_sdp); + ACCESS_ONCE(e->src) = src_sdp; + ACCESS_ONCE(e->dst) = dst_sdp; + ACCESS_ONCE(e->jiffies) = jiffies; + good_bytes = 0; req->__data_len = blk_rq_bytes(req); req->cmd_flags |= REQ_QUIET; -- 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 8/15] block copy: introduce "copy_boundary" limits
There is no way to split copy requests, so the creator of the requests (the function blkdev_issue_copy) must make requests with proper size. Device mapper splits the requests at a boundary between targets or at a boundary specified by each target driver. We must make sure that the copy requets do not cross these boundaries. This patch introduces a new queue limit "copy_boundary", it is log2 of the boundary in sectors that the request must not cross. Device mapper will use this limit to propagate its requirements through the device stack. Signed-off-by: Mikulas Patocka--- block/blk-lib.c| 21 - block/blk-settings.c | 17 + block/blk-sysfs.c | 13 + include/linux/blkdev.h |1 + 4 files changed, 51 insertions(+), 1 deletion(-) Index: linux-4.4-rc4/block/blk-settings.c === --- linux-4.4-rc4.orig/block/blk-settings.c 2015-12-10 17:04:30.0 +0100 +++ linux-4.4-rc4/block/blk-settings.c 2015-12-10 17:04:54.0 +0100 @@ -96,6 +96,7 @@ void blk_set_default_limits(struct queue lim->chunk_sectors = 0; lim->max_write_same_sectors = 0; lim->max_copy_sectors = 0; + lim->copy_boundary = 63; lim->max_discard_sectors = 0; lim->max_hw_discard_sectors = 0; lim->discard_granularity = 0; @@ -311,6 +312,18 @@ void blk_queue_max_copy_sectors(struct r EXPORT_SYMBOL(blk_queue_max_copy_sectors); /** + * blk_queue_copy_boundary - set a boundary for copy operations. No copy + * operation may cross the boundary + * @q: the request queue for the device + * @copy_boundary: log2 of the copy boundary in sectors + **/ +void blk_queue_copy_boundary(struct request_queue *q, +unsigned char copy_boundary) +{ + q->limits.copy_boundary = copy_boundary; +} + +/** * blk_queue_max_segments - set max hw segments for a request for this queue * @q: the request queue for the device * @max_segments: max number of segments @@ -552,6 +565,10 @@ int blk_stack_limits(struct queue_limits t->max_segment_size = min_not_zero(t->max_segment_size, b->max_segment_size); + t->copy_boundary = min(t->copy_boundary, b->copy_boundary); + if (start) + t->copy_boundary = min(t->copy_boundary, (unsigned char)__ffs64(start)); + t->misaligned |= b->misaligned; alignment = queue_limit_alignment_offset(b, start); Index: linux-4.4-rc4/block/blk-sysfs.c === --- linux-4.4-rc4.orig/block/blk-sysfs.c2015-12-10 17:04:30.0 +0100 +++ linux-4.4-rc4/block/blk-sysfs.c 2015-12-10 17:04:54.0 +0100 @@ -199,6 +199,13 @@ static ssize_t queue_copy_max_show(struc (unsigned long long)q->limits.max_copy_sectors << 9); } +static ssize_t queue_copy_boundary_show(struct request_queue *q, char *page) +{ + return sprintf(page, "%llu\n", + !q->limits.max_copy_sectors || q->limits.copy_boundary == 63 ? + 0ULL : 512ULL << q->limits.copy_boundary); +} + static ssize_t queue_max_sectors_store(struct request_queue *q, const char *page, size_t count) { @@ -453,6 +460,11 @@ static struct queue_sysfs_entry queue_co .show = queue_copy_max_show, }; +static struct queue_sysfs_entry queue_copy_boundary_entry = { + .attr = {.name = "copy_boundary_bytes", .mode = S_IRUGO }, + .show = queue_copy_boundary_show, +}; + static struct queue_sysfs_entry queue_nonrot_entry = { .attr = {.name = "rotational", .mode = S_IRUGO | S_IWUSR }, .show = queue_show_nonrot, @@ -509,6 +521,7 @@ static struct attribute *default_attrs[] _discard_zeroes_data_entry.attr, _write_same_max_entry.attr, _copy_max_entry.attr, + _copy_boundary_entry.attr, _nonrot_entry.attr, _nomerges_entry.attr, _rq_affinity_entry.attr, Index: linux-4.4-rc4/include/linux/blkdev.h === --- linux-4.4-rc4.orig/include/linux/blkdev.h 2015-12-10 17:04:46.0 +0100 +++ linux-4.4-rc4/include/linux/blkdev.h2015-12-10 17:04:54.0 +0100 @@ -273,6 +273,7 @@ struct queue_limits { unsigned short max_segments; unsigned short max_integrity_segments; + unsigned char copy_boundary; unsigned char misaligned; unsigned char discard_misaligned; unsigned char cluster; Index: linux-4.4-rc4/block/blk-lib.c === --- linux-4.4-rc4.orig/block/blk-lib.c 2015-12-10 17:04:46.0 +0100 +++ linux-4.4-rc4/block/blk-lib.c 2015-12-10 17:04:54.0 +0100 @@ -447,6 +447,12 @@ int blkdev_issue_copy(struct
[PATCH 6/15] scsi xcopy: suppress error messages
This patch suppresses error messages when copying between two arrays that support XCOPY each, but that cannot copy data between each other. Signed-off-by: Mikulas Patocka--- drivers/scsi/sd.c | 14 ++ 1 file changed, 14 insertions(+) Index: linux-4.4-rc4/drivers/scsi/sd.c === --- linux-4.4-rc4.orig/drivers/scsi/sd.c2015-12-07 16:58:48.0 +0100 +++ linux-4.4-rc4/drivers/scsi/sd.c 2015-12-07 16:59:09.0 +0100 @@ -1995,6 +1995,20 @@ static int sd_done(struct scsi_cmnd *SCp req->cmd_flags |= REQ_QUIET; } } + } else if (sshdr.asc == 0x26) { + switch (op) { + /* +* Copying between two arrays that support XCOPY, but +* cannot access each other. +*/ + case EXTENDED_COPY: + if ((SCpnt->cmnd[1] & 0x1f) == 0) { + good_bytes = 0; + req->__data_len = blk_rq_bytes(req); + req->cmd_flags |= REQ_QUIET; + } + break; + } } break; default: -- 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] hisi_sas: fix error codes in hisi_sas_task_prep()
> "Dan" == Dan Carpenterwrites: Dan> There were a couple cases where the error codes weren't set and Dan> also I changed the success return to "return 0;" which is the same Dan> as "return rc;" but more explicit. Applied to 4.5/scsi-queue. -- Martin K. Petersen Oracle Linux Engineering -- 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 05/13] irq_poll: mark __irq_poll_complete static
On 12/07/2015 12:51 PM, Christoph Hellwig wrote: [ ... ] Reviewed-by: Bart Van Assche-- 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 06/13] irq_poll: remove unused data and max fields
On 12/07/2015 12:51 PM, Christoph Hellwig wrote: [ ... ] Reviewed-by: Bart Van Assche-- 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 07/13] IB: add a proper completion queue abstraction
On 12/07/2015 12:51 PM, Christoph Hellwig wrote: This adds an abstraction that allows ULP to simply pass a completion ^^^ I think this should either be changed into either "an ULP" or "ULPs". +/** + * ib_process_direct_cq - process a CQ in caller context + * @cq:CQ to process + * @budget:number of CQEs to poll for + * + * This function is used to process all outstanding CQ entries on a + * %IB_POLL_DIRECT CQ. It does not offload CQ processing to a different + * context and does not ask from completion interrupts from the HCA. Should this perhaps be changed into "for" ? + * + * Note: for compatibility reasons -1 can be passed in %budget for unlimited + * polling. Do not use this feature in new code, it will be remove soon. ^^ Did you perhaps intend "removed" ? +struct ib_cq *ib_alloc_cq(struct ib_device *dev, void *private, + int nr_cqe, int comp_vector, enum ib_poll_context poll_ctx) +{ > [ ... ] + cq->wc = kmalloc_array(IB_POLL_BATCH, sizeof(*cq->wc), GFP_KERNEL); Why is the wc array allocated separately instead of being embedded in struct ib_cq ? I think the faster completion queues can be created the better so if it is possible to eliminate the above kmalloc() call I would prefer that. --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c @@ -457,10 +457,11 @@ static struct srp_fr_pool *srp_alloc_fr_pool(struct srp_target_port *target) static void srp_destroy_qp(struct srp_rdma_ch *ch) { static struct ib_qp_attr attr = { .qp_state = IB_QPS_ERR }; - static struct ib_recv_wr wr = { .wr_id = SRP_LAST_WR_ID }; + static struct ib_recv_wr wr = { 0 }; struct ib_recv_wr *bad_wr; int ret; Is explicit initialization to "{ 0 }" really needed for static structures ? 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
[PATCH 0/15] copy offload patches
Hi This patch series adds copy offload (the XCOPY command) to the block layer, SCSI subsystems and device mapper. The principle of operation is this: We create two bios with REQ_COPY flag, one for read and one for write. The bios have no data pages and they both point to the same bio_copy structure. The bios may be submitted to the same logical volume or to different logical volumes. The bios go independently through the device mapper stack and when they both reach the physical device (the function blk_queue_bio), the bio pair is collected and the XCOPY request is sent to the SCSI device. Mikulas -- 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 2/15] block copy: use two bios
This patch changes the architecture of xcopy so that two bios are used. There used to be just one bio that held pointers to both source and destination block device. However a bio with two block devices cannot really be passed though block midlayer drivers (dm and md). When we need to send the XCOPY command, we call the function blkdev_issue_copy. This function creates two bios, the first with bi_rw READ | REQ_COPY and the second WRITE | REQ_COPY. The bios have a pointer to a common bi_copy structure. These bios travel independently through the block device stack. When both the bios reach the physical disk driver (the function blk_queue_bio), they are paired, a request is made and the request is sent to the SCSI disk driver. It is possible that one of the bios reaches a device that doesn't support XCOPY, in that case both bios are aborted with an error. Note that there is no guarantee that the XCOPY command will succeed. If it doesn't succeed, the caller is supposed to perform the copy manually. Signed-off-by: Mikulas Patocka--- block/bio.c | 28 +++- block/blk-core.c | 41 block/blk-lib.c | 78 +- drivers/scsi/sd.c |7 +--- include/linux/blk_types.h | 12 +-- 5 files changed, 142 insertions(+), 24 deletions(-) Index: linux-4.4-rc4/block/blk-lib.c === --- linux-4.4-rc4.orig/block/blk-lib.c 2015-12-10 17:08:11.0 +0100 +++ linux-4.4-rc4/block/blk-lib.c 2015-12-10 17:59:40.0 +0100 @@ -300,6 +300,38 @@ int blkdev_issue_zeroout(struct block_de } EXPORT_SYMBOL(blkdev_issue_zeroout); +static void bio_copy_end_io(struct bio *bio) +{ + struct bio_copy *bc = bio->bi_copy; + if (unlikely(bio->bi_error)) { + unsigned long flags; + int dir; + struct bio *other; + + /* if the other bio is waiting for the pair, release it */ + spin_lock_irqsave(>spinlock, flags); + if (bc->error >= 0) + bc->error = bio->bi_error; + dir = bio_data_dir(bio); + other = bc->pair[dir ^ 1]; + bc->pair[dir ^ 1] = NULL; + spin_unlock_irqrestore(>spinlock, flags); + if (other) { + other->bi_error = bio->bi_error; + bio_endio(other); + } + } + bio_put(bio); + if (atomic_dec_and_test(>in_flight)) { + struct bio_batch *bb = bc->private; + if (unlikely(bc->error < 0) && !ACCESS_ONCE(bb->error)) + ACCESS_ONCE(bb->error) = bc->error; + kfree(bc); + if (atomic_dec_and_test(>done)) + complete(bb->wait); + } +} + /** * blkdev_issue_copy - queue a copy same operation * @src_bdev: source blockdev @@ -346,9 +378,9 @@ int blkdev_issue_copy(struct block_devic bb.wait = while (nr_sects) { - struct bio *bio; + struct bio *read_bio, *write_bio; struct bio_copy *bc; - unsigned int chunk; + unsigned int chunk = min(nr_sects, max_copy_sectors); bc = kmalloc(sizeof(struct bio_copy), gfp_mask); if (!bc) { @@ -356,27 +388,43 @@ int blkdev_issue_copy(struct block_devic break; } - bio = bio_alloc(gfp_mask, 1); - if (!bio) { + read_bio = bio_alloc(gfp_mask, 1); + if (!read_bio) { kfree(bc); ret = -ENOMEM; break; } - chunk = min(nr_sects, max_copy_sectors); - - bio->bi_iter.bi_sector = dst_sector; - bio->bi_iter.bi_size = chunk << 9; - bio->bi_end_io = bio_batch_end_io; - bio->bi_bdev = dst_bdev; - bio->bi_private = - bio->bi_copy = bc; + write_bio = bio_alloc(gfp_mask, 1); + if (!write_bio) { + bio_put(read_bio); + kfree(bc); + ret = -ENOMEM; + break; + } - bc->bic_bdev = src_bdev; - bc->bic_sector = src_sector; + atomic_set(>in_flight, 2); + bc->error = 1; + bc->pair[0] = NULL; + bc->pair[1] = NULL; + bc->private = + spin_lock_init(>spinlock); + + read_bio->bi_iter.bi_sector = src_sector; + read_bio->bi_iter.bi_size = chunk << 9; + read_bio->bi_end_io = bio_copy_end_io; + read_bio->bi_bdev = src_bdev; + read_bio->bi_copy = bc; + +
[PATCH 4/15] block copy: use a timer to fix a theoretical deadlock
The block layer creates two bios for each copy operation. The bios travel independently through the storage stack and they are paired at the block device. There is a theoretical problem with this - the block device stack only guarantees forward progress for a single bio. When two bios are sent, it is possible (though very unlikely) that the first bio exhausts some mempool and the second bio waits until there is free space in the mempool (and thus it waits until the first bio finishes). To avoid this deadlock, we introduce a timer. If the two bios are not paired at the physical block device within 10 seconds, the copy operation is aborted and the bio that waits to be paired is released with an error. Note that there is no guarantee that any XCOPY operation succeed, so aborting an operation with an error shouldn't cause any problems - the caller is supposed to perform the copy manually if XCOPY fails. Signed-off-by: Mikulas Patocka--- block/blk-lib.c | 31 +++ include/linux/blk_types.h |2 ++ 2 files changed, 33 insertions(+) Index: linux-4.3/block/blk-lib.c === --- linux-4.3.orig/block/blk-lib.c 2015-11-02 18:43:06.0 +0100 +++ linux-4.3/block/blk-lib.c 2015-11-02 18:43:10.0 +0100 @@ -300,6 +300,34 @@ int blkdev_issue_zeroout(struct block_de } EXPORT_SYMBOL(blkdev_issue_zeroout); +#define BLK_COPY_TIMEOUT (10 * HZ) + +static void blk_copy_timeout(unsigned long bc_) +{ + struct bio_copy *bc = (struct bio_copy *)bc_; + struct bio *bio0 = NULL, *bio1 = NULL; + + WARN_ON(!irqs_disabled()); + + spin_lock(>spinlock); /* the timer is IRQSAFE */ + if (bc->error == 1) { + bc->error = -ETIMEDOUT; + bio0 = bc->pair[0]; + bio1 = bc->pair[1]; + bc->pair[0] = bc->pair[1] = NULL; + } + spin_unlock(>spinlock); + + if (bio0) { + bio0->bi_error = -ETIMEDOUT; + bio_endio(bio0); + } + if (bio1) { + bio1->bi_error = -ETIMEDOUT; + bio_endio(bio1); + } +} + static void bio_copy_end_io(struct bio *bio) { struct bio_copy *bc = bio->bi_copy; @@ -335,6 +363,7 @@ static void bio_copy_end_io(struct bio * } while (unlikely(atomic64_cmpxchg(bc->first_error, first_error, bc->offset) != first_error)); } + del_timer_sync(>timer); kfree(bc); if (atomic_dec_and_test(>done)) complete(bb->wait); @@ -425,6 +454,8 @@ int blkdev_issue_copy(struct block_devic bc->first_error = _error; bc->offset = offset; spin_lock_init(>spinlock); + __setup_timer(>timer, blk_copy_timeout, (unsigned long)bc, TIMER_IRQSAFE); + mod_timer(>timer, jiffies + BLK_COPY_TIMEOUT); read_bio->bi_iter.bi_sector = src_sector; read_bio->bi_iter.bi_size = chunk << 9; Index: linux-4.3/include/linux/blk_types.h === --- linux-4.3.orig/include/linux/blk_types.h2015-11-02 18:43:06.0 +0100 +++ linux-4.3/include/linux/blk_types.h 2015-11-02 18:43:10.0 +0100 @@ -6,6 +6,7 @@ #define __LINUX_BLK_TYPES_H #include +#include struct bio_set; struct bio; @@ -52,6 +53,7 @@ struct bio_copy { atomic64_t *first_error; sector_t offset; spinlock_t spinlock; + struct timer_list timer; }; /* -- 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 3/15] block copy: report the amount of copied data
This patch changes blkdev_issue_copy so that it returns the number of copied sectors in the variable "copied". The kernel makes best effort to copy as much data as possible, but because of device mapper mapping, it may be possible that copying fails at some stage. If we just returned the error number, the caller wouldn't know if all or part of the operation failed and the caller would be required to redo the whole copy operation. We return the number of copied sectors so that the caller can skip these sectors when doing the copy manually. On success (zero return code), the number of copied sectors is equal to the number of requested sectors. On error (negative return code), the number of copied sectors is smaller than the number of requested sectors. The number of copied bytes is returned as a fourth uint64_t argument in the BLKCOPY ioctl. Signed-off-by: Mikulas Patocka--- block/blk-lib.c | 30 +- block/ioctl.c | 25 - include/linux/blk_types.h |2 ++ include/linux/blkdev.h|3 ++- 4 files changed, 45 insertions(+), 15 deletions(-) Index: linux-4.4-rc4/block/blk-lib.c === --- linux-4.4-rc4.orig/block/blk-lib.c 2015-12-10 17:04:38.0 +0100 +++ linux-4.4-rc4/block/blk-lib.c 2015-12-10 17:04:40.0 +0100 @@ -324,8 +324,17 @@ static void bio_copy_end_io(struct bio * bio_put(bio); if (atomic_dec_and_test(>in_flight)) { struct bio_batch *bb = bc->private; - if (unlikely(bc->error < 0) && !ACCESS_ONCE(bb->error)) - ACCESS_ONCE(bb->error) = bc->error; + if (unlikely(bc->error < 0)) { + u64 first_error; + if (!ACCESS_ONCE(bb->error)) + ACCESS_ONCE(bb->error) = bc->error; + do { + first_error = atomic64_read(bc->first_error); + if (bc->offset >= first_error) + break; + } while (unlikely(atomic64_cmpxchg(bc->first_error, + first_error, bc->offset) != first_error)); + } kfree(bc); if (atomic_dec_and_test(>done)) complete(bb->wait); @@ -346,7 +355,7 @@ static void bio_copy_end_io(struct bio * */ int blkdev_issue_copy(struct block_device *src_bdev, sector_t src_sector, struct block_device *dst_bdev, sector_t dst_sector, - unsigned int nr_sects, gfp_t gfp_mask) + sector_t nr_sects, gfp_t gfp_mask, sector_t *copied) { DECLARE_COMPLETION_ONSTACK(wait); struct request_queue *sq = bdev_get_queue(src_bdev); @@ -354,6 +363,11 @@ int blkdev_issue_copy(struct block_devic unsigned int max_copy_sectors; struct bio_batch bb; int ret = 0; + atomic64_t first_error = ATOMIC64_INIT(nr_sects); + sector_t offset = 0; + + if (copied) + *copied = 0; if (!sq || !dq) return -ENXIO; @@ -377,10 +391,10 @@ int blkdev_issue_copy(struct block_devic bb.error = 0; bb.wait = - while (nr_sects) { + while (nr_sects && !ACCESS_ONCE(bb.error)) { struct bio *read_bio, *write_bio; struct bio_copy *bc; - unsigned int chunk = min(nr_sects, max_copy_sectors); + unsigned chunk = (unsigned)min(nr_sects, (sector_t)max_copy_sectors); bc = kmalloc(sizeof(struct bio_copy), gfp_mask); if (!bc) { @@ -408,6 +422,8 @@ int blkdev_issue_copy(struct block_devic bc->pair[0] = NULL; bc->pair[1] = NULL; bc->private = + bc->first_error = _error; + bc->offset = offset; spin_lock_init(>spinlock); read_bio->bi_iter.bi_sector = src_sector; @@ -429,12 +445,16 @@ int blkdev_issue_copy(struct block_devic src_sector += chunk; dst_sector += chunk; nr_sects -= chunk; + offset += chunk; } /* Wait for bios in-flight */ if (!atomic_dec_and_test()) wait_for_completion_io(); + if (copied) + *copied = min((sector_t)atomic64_read(_error), offset); + if (likely(!ret)) ret = bb.error; Index: linux-4.4-rc4/include/linux/blk_types.h === --- linux-4.4-rc4.orig/include/linux/blk_types.h2015-12-10 17:04:38.0 +0100 +++ linux-4.4-rc4/include/linux/blk_types.h 2015-12-10 17:04:40.0 +0100 @@ -49,6 +49,8 @@ struct bio_copy { atomic_t in_flight; struct bio
Re: [PATCH RESEND] cxlflash: drop unlikely before IS_ERR_OR_NULL
> "Matthew" == Matthew R Ochswrites: Matthew> IS_ERR_OR_NULL already contain an unlikely compiler flag. Drop Matthew> it. Applied to 4.5/scsi-queue. -- Martin K. Petersen Oracle Linux Engineering -- 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] VMW_PVSCSI: Fix the issue of DMA-API related warnings.
> "Josh" == Josh Boyerwrites: Josh> The driver is missing calls to pci_dma_mapping_error() after Josh> performing the DMA mapping, which caused DMA-API warning to show Josh> up in dmesg's output. Though that happens only when DMA_API_DEBUG Josh> option is enabled. This change fixes the issue and makes Josh> pvscsi_map_buffers() function more robust. Applied to 4.5/scsi-queue. -- Martin K. Petersen Oracle Linux Engineering -- 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] osd: fix signed char versus %02x issue
> "Rasmus" == Rasmus Villemoeswrites: Rasmus> If char is signed and one of these bytes happen to have a value Rasmus> outside the ascii range, the corresponding output will consist Rasmus> of "ff" followed by the two hex chars that were actually Rasmus> intended. One way to fix it would be to change the casts to Rasmus> (u8*) aka (unsigned char*), but it is much simpler (and Rasmus> generates smaller code) to use the %ph extension which was Rasmus> created for such short hexdumps. Applied to 4.5/scsi-queue. -- Martin K. Petersen Oracle Linux Engineering -- 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 01/13] irq_poll: make blk-iopoll available outside the block layer
On 12/07/2015 12:51 PM, Christoph Hellwig wrote: -enum { - IOPOLL_F_SCHED = 0, - IOPOLL_F_DISABLE= 1, -}; [ ... ] +enum { + IRQ_POLL_F_SCHED= 0, + IRQ_POLL_F_DISABLE = 1, +}; A nitpick: the values of these constants were aligned in the original code but no longer in the new code. Whether or not this gets addressed: Reviewed-by: Bart Van Assche-- 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 5/15] block copy: use asynchronous notification
In dm-snapshot target there may be large number of copy requests in progress. If every pending copy request consumed a process context, it would put too much load on the system. To avoid this load, we need asynchronous notification when copy finishes - we can pass a callback to the function blkdev_issue_copy, if the callback is non-NULL, blkdev_issue_copy exits when it submits all the copy bios and the callback is called when the copy operation finishes. With the callback mechanism, there can be large number of in-progress copy requests and we do not need process context for each of them. Signed-off-by: Mikulas Patocka--- block/blk-lib.c | 148 +- block/ioctl.c |2 include/linux/blk_types.h |5 - include/linux/blkdev.h|2 4 files changed, 112 insertions(+), 45 deletions(-) Index: linux-4.4-rc4/block/blk-lib.c === --- linux-4.4-rc4.orig/block/blk-lib.c 2015-12-10 17:04:45.0 +0100 +++ linux-4.4-rc4/block/blk-lib.c 2015-12-10 17:04:46.0 +0100 @@ -300,6 +300,17 @@ int blkdev_issue_zeroout(struct block_de } EXPORT_SYMBOL(blkdev_issue_zeroout); +struct bio_copy_batch { + atomic_long_t done; + int async_error; + int sync_error; + sector_t sync_copied; + atomic64_t first_error; + void (*callback)(void *data, int error); + void *data; + sector_t *copied; +}; + #define BLK_COPY_TIMEOUT (10 * HZ) static void blk_copy_timeout(unsigned long bc_) @@ -328,6 +339,18 @@ static void blk_copy_timeout(unsigned lo } } +static void blk_copy_batch_finish(struct bio_copy_batch *batch) +{ + void (*fn)(void *, int) = batch->callback; + void *data = batch->data; + int error = unlikely(batch->sync_error) ? batch->sync_error : batch->async_error; + if (batch->copied) + *batch->copied = min(batch->sync_copied, (sector_t)atomic64_read(>first_error)); + kfree(batch); + if (fn) + fn(data, error); +} + static void bio_copy_end_io(struct bio *bio) { struct bio_copy *bc = bio->bi_copy; @@ -351,25 +374,37 @@ static void bio_copy_end_io(struct bio * } bio_put(bio); if (atomic_dec_and_test(>in_flight)) { - struct bio_batch *bb = bc->private; + struct bio_copy_batch *batch = bc->batch; if (unlikely(bc->error < 0)) { u64 first_error; - if (!ACCESS_ONCE(bb->error)) - ACCESS_ONCE(bb->error) = bc->error; + if (!ACCESS_ONCE(batch->async_error)) + ACCESS_ONCE(batch->async_error) = bc->error; do { - first_error = atomic64_read(bc->first_error); + first_error = atomic64_read(>first_error); if (bc->offset >= first_error) break; - } while (unlikely(atomic64_cmpxchg(bc->first_error, + } while (unlikely(atomic64_cmpxchg(>first_error, first_error, bc->offset) != first_error)); } del_timer_sync(>timer); kfree(bc); - if (atomic_dec_and_test(>done)) - complete(bb->wait); + if (atomic_long_dec_and_test(>done)) + blk_copy_batch_finish(batch); } } +struct bio_copy_completion { + struct completion wait; + int error; +}; + +static void bio_copy_sync_callback(void *ptr, int error) +{ + struct bio_copy_completion *comp = ptr; + comp->error = error; + complete(>wait); +} + /** * blkdev_issue_copy - queue a copy same operation * @src_bdev: source blockdev @@ -384,57 +419,83 @@ static void bio_copy_end_io(struct bio * */ int blkdev_issue_copy(struct block_device *src_bdev, sector_t src_sector, struct block_device *dst_bdev, sector_t dst_sector, - sector_t nr_sects, gfp_t gfp_mask, sector_t *copied) + sector_t nr_sects, gfp_t gfp_mask, + void (*callback)(void *, int), void *data, + sector_t *copied) { DECLARE_COMPLETION_ONSTACK(wait); struct request_queue *sq = bdev_get_queue(src_bdev); struct request_queue *dq = bdev_get_queue(dst_bdev); unsigned int max_copy_sectors; - struct bio_batch bb; - int ret = 0; - atomic64_t first_error = ATOMIC64_INIT(nr_sects); - sector_t offset = 0; + int ret; + struct bio_copy_batch *batch; + struct bio_copy_completion comp; if (copied) *copied = 0; - if (!sq || !dq) - return -ENXIO; +
Re: [PATCH 02/13] irq_poll: don't disable new irq_poll instances
On 12/07/2015 12:51 PM, Christoph Hellwig wrote: There is no good reason to start out disabled - drivers can control if the poll instance can be scheduled by simply not scheduling it yet. Reviewed-by: Bart Van Assche-- 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 3/9] aacraid: Added EEH support
From: Raghava Aditya RenukuntaAdded support for PCI EEH(extended error handling). Changes in V2: Made local functions static Removed call to aac_fib_free_tag Set adapter_shutdown flag when PCI error detected Signed-off-by: Raghava Aditya Renukunta --- drivers/scsi/aacraid/aacraid.h | 1 + drivers/scsi/aacraid/linit.c | 140 + 2 files changed, 141 insertions(+) diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index fff1306..2916288 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -1235,6 +1235,7 @@ struct aac_dev struct msix_entry msixentry[AAC_MAX_MSIX]; struct aac_msix_ctx aac_msix[AAC_MAX_MSIX]; /* context */ u8 adapter_shutdown; + u32 handle_pci_error; }; #define aac_adapter_interrupt(dev) \ diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 129a515..08c6835 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -38,6 +38,7 @@ #include #include #include +#include #include #include #include @@ -1298,6 +1299,9 @@ static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) goto out_deinit; scsi_scan_host(shost); + pci_enable_pcie_error_reporting(pdev); + pci_save_state(pdev); + return 0; out_deinit: @@ -1501,6 +1505,141 @@ static void aac_remove_one(struct pci_dev *pdev) } } +static void aac_flush_ios(struct aac_dev *aac) +{ + int i; + struct scsi_cmnd *cmd; + + for (i = 0; i < aac->scsi_host_ptr->can_queue; i++) { + cmd = (struct scsi_cmnd *)aac->fibs[i].callback_data; + if (cmd && (cmd->SCp.phase == AAC_OWNER_FIRMWARE)) { + scsi_dma_unmap(cmd); + + if (aac->handle_pci_error) + cmd->result = DID_NO_CONNECT << 16; + else + cmd->result = DID_RESET << 16; + + cmd->scsi_done(cmd); + } + } +} + +static pci_ers_result_t aac_pci_error_detected(struct pci_dev *pdev, + enum pci_channel_state error) +{ + struct Scsi_Host *shost = pci_get_drvdata(pdev); + struct aac_dev *aac = shost_priv(shost); + + dev_err(>dev, "aacraid: PCI error detected %x\n", error); + + switch (error) { + case pci_channel_io_normal: + return PCI_ERS_RESULT_CAN_RECOVER; + case pci_channel_io_frozen: + + aac->handle_pci_error = 1; + aac->adapter_shutdown = 1; + + scsi_block_requests(aac->scsi_host_ptr); + aac_flush_ios(aac); + aac_release_resources(aac); + + pci_disable_pcie_error_reporting(pdev); + aac_adapter_ioremap(aac, 0); + + return PCI_ERS_RESULT_NEED_RESET; + case pci_channel_io_perm_failure: + aac->handle_pci_error = 1; + aac->adapter_shutdown = 1; + + aac_flush_ios(aac); + return PCI_ERS_RESULT_DISCONNECT; + } + + return PCI_ERS_RESULT_NEED_RESET; +} + +static pci_ers_result_t aac_pci_mmio_enabled(struct pci_dev *pdev) +{ + dev_err(>dev, "aacraid: PCI error - mmio enabled\n"); + return PCI_ERS_RESULT_NEED_RESET; +} + +static pci_ers_result_t aac_pci_slot_reset(struct pci_dev *pdev) +{ + dev_err(>dev, "aacraid: PCI error - slot reset\n"); + pci_restore_state(pdev); + if (pci_enable_device(pdev)) { + dev_warn(>dev, + "aacraid: failed to enable slave\n"); + goto fail_device; + } + + pci_set_master(pdev); + + if (pci_enable_device_mem(pdev)) { + dev_err(>dev, "pci_enable_device_mem failed\n"); + goto fail_device; + } + + return PCI_ERS_RESULT_RECOVERED; + +fail_device: + dev_err(>dev, "aacraid: PCI error - slot reset failed\n"); + return PCI_ERS_RESULT_DISCONNECT; +} + + +static void aac_pci_resume(struct pci_dev *pdev) +{ + struct Scsi_Host *shost = pci_get_drvdata(pdev); + struct scsi_device *sdev = NULL; + struct aac_dev *aac = (struct aac_dev *)shost_priv(shost); + + pci_cleanup_aer_uncorrect_error_status(pdev); + + if (aac_adapter_ioremap(aac, aac->base_size)) { + + dev_err(>dev, "aacraid: ioremap failed\n"); + /* remap failed, go back ... */ + aac->comm_interface = AAC_COMM_PRODUCER; + if (aac_adapter_ioremap(aac, AAC_MIN_FOOTPRINT_SIZE)) { + dev_warn(>dev, + "aacraid: unable to map adapter.\n"); + + return; + } + } + +
[PATCH v2 8/9] aacraid: Fix character device re-initialization
From: Raghava Aditya RenukuntaDuring EEH PCI hotplug activity kernel unloads and loads the driver, causing character device to be unregistered(aac_remove_one).When the driver is loaded back using aac_probe_one the character device needs to be registered again for the AIF management tools to work. Fixed by adding code to register character device in aac_probe_one if it is unregistered in aac_remove_one. Changes in V2: Added macros to track character device state Signed-off-by: Raghava Aditya Renukunta --- drivers/scsi/aacraid/aacraid.h | 7 +++ drivers/scsi/aacraid/linit.c | 21 ++--- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 2916288..a440840 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -94,6 +94,13 @@ enum { #define aac_phys_to_logical(x) ((x)+1) #define aac_logical_to_phys(x) ((x)?(x)-1:0) +/* + * These macros are for keeping track of + * character device state. + */ +#define AAC_CHARDEV_UNREGISTERED (-1) +#define AAC_CHARDEV_NEEDS_REINIT (-2) + /* #define AAC_DETAILED_STATUS_INFO */ struct diskparm diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 6944560..fea1ba1 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -80,7 +80,7 @@ MODULE_VERSION(AAC_DRIVER_FULL_VERSION); static DEFINE_MUTEX(aac_mutex); static LIST_HEAD(aac_devices); -static int aac_cfg_major = -1; +static int aac_cfg_major = AAC_CHARDEV_UNREGISTERED; char aac_driver_version[] = AAC_DRIVER_FULL_VERSION; /* @@ -1123,6 +1123,13 @@ static void __aac_shutdown(struct aac_dev * aac) else if (aac->max_msix > 1) pci_disable_msix(aac->pdev); } +static void aac_init_char(void) +{ + aac_cfg_major = register_chrdev(0, "aac", _cfg_fops); + if (aac_cfg_major < 0) { + pr_err("aacraid: unable to register \"aac\" device.\n"); + } +} static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) { @@ -1180,6 +1187,9 @@ static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) shost->max_cmd_len = 16; shost->use_cmd_list = 1; + if (aac_cfg_major == AAC_CHARDEV_NEEDS_REINIT) + aac_init_char(); + aac = (struct aac_dev *)shost->hostdata; aac->base_start = pci_resource_start(pdev, 0); aac->scsi_host_ptr = shost; @@ -1517,7 +1527,7 @@ static void aac_remove_one(struct pci_dev *pdev) pci_disable_device(pdev); if (list_empty(_devices)) { unregister_chrdev(aac_cfg_major, "aac"); - aac_cfg_major = -1; + aac_cfg_major = AAC_CHARDEV_NEEDS_REINIT; } } @@ -1680,11 +1690,8 @@ static int __init aac_init(void) if (error < 0) return error; - aac_cfg_major = register_chrdev( 0, "aac", _cfg_fops); - if (aac_cfg_major < 0) { - printk(KERN_WARNING - "aacraid: unable to register \"aac\" device.\n"); - } + aac_init_char(); + return 0; } -- 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 v2 5/9] aacraid: Set correct msix count for EEH recovery
From: Raghava Aditya RenukuntaDuring EEH recovery number of online CPU's might change thereby changing the number of MSIx vectors. Since each fib is allocated to a vector, changes in the number of vectors causes fib to be sent thru invalid vectors.In addition the correct number of MSIx vectors is not updated in the INIT struct sent to the controller, when it is reinitialized. Fixed by reassigning vectors to fibs based on the updated number of MSIx vectors and updating the INIT structure before sending to controller. Changes in V2: Replaced fib vector allocation code with aac_fib_vector_assign Signed-off-by: Raghava Aditya Renukunta --- drivers/scsi/aacraid/linit.c | 12 +++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 08c6835..6d79181 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -1410,8 +1410,18 @@ static int aac_acquire_resources(struct aac_dev *dev) aac_adapter_enable_int(dev); - if (!dev->sync_mode) + /*max msix may change after EEH +* Re-assign vectors to fibs +*/ + aac_fib_vector_assign(dev); + + if (!dev->sync_mode) { + /* After EEH recovery or suspend resume, max_msix count +* may change, therfore updating in init as well. +*/ aac_adapter_start(dev); + dev->init->Sa_MSIXVectors = cpu_to_le32(dev->max_msix); + } return 0; error_iounmap: -- 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 v2 7/9] aacraid: Fix AIF triggered IOP_RESET
From: Raghava Aditya Renukuntawhile driver removal is in progress or PCI shutdown is invoked, driver kills AIF aacraid thread, but IOCTL requests from the management tools re-start AIF thread leading to IOP_RESET. Fixed by setting adapter_shutdown flag when PCI shutdown is invoked. Changes in V2: Set adapter_shutdown flag before shutdown command is sent to \ controller Signed-off-by: Raghava Aditya Renukunta --- drivers/scsi/aacraid/comminit.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/scsi/aacraid/comminit.c b/drivers/scsi/aacraid/comminit.c index 0e954e3..fe08854 100644 --- a/drivers/scsi/aacraid/comminit.c +++ b/drivers/scsi/aacraid/comminit.c @@ -212,8 +212,9 @@ int aac_send_shutdown(struct aac_dev * dev) return -ENOMEM; aac_fib_init(fibctx); - cmd = (struct aac_close *) fib_data(fibctx); + dev->adapter_shutdown = 1; + cmd = (struct aac_close *) fib_data(fibctx); cmd->command = cpu_to_le32(VM_CloseAll); cmd->cid = cpu_to_le32(0xfffe); @@ -229,7 +230,6 @@ int aac_send_shutdown(struct aac_dev * dev) /* FIB should be freed only after getting the response from the F/W */ if (status != -ERESTARTSYS) aac_fib_free(fibctx); - dev->adapter_shutdown = 1; if ((dev->pdev->device == PMC_DEVICE_S7 || dev->pdev->device == PMC_DEVICE_S8 || dev->pdev->device == PMC_DEVICE_S9) && -- 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 v2 1/9] aacraid: SCSI blk tag support
From: Raghava Aditya RenukuntaThe method to allocate and free FIB's in the present code utilizes spinlocks.Multiple IO's have to wait on the spinlock to acquire or free fibs creating a performance bottleneck. An alternative solution would be to use block layer tags to keep track of the fibs allocated and freed. To this end aac_fib_alloc_tag was created to utilize the blk layer tags to plug into the Fib pool.These functions are used exclusively in the IO path. 8 fibs are reserved for the use of AIF management software and utilize the previous spinlock based implementations. Changes in V2: Removed aac_fib_free_tag since it was a stub function Moved population of fib fields that are constant to aac_fib_setup Signed-off-by: Raghava Aditya Renukunta --- drivers/scsi/aacraid/aachba.c | 27 --- drivers/scsi/aacraid/aacraid.h | 1 + drivers/scsi/aacraid/commsup.c | 32 +--- drivers/scsi/aacraid/dpcsup.c | 2 -- drivers/scsi/aacraid/linit.c | 2 ++ 5 files changed, 44 insertions(+), 20 deletions(-) diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index e4c2437..7dfd0fa 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c @@ -323,7 +323,6 @@ static inline int aac_valid_context(struct scsi_cmnd *scsicmd, if (unlikely(!scsicmd || !scsicmd->scsi_done)) { dprintk((KERN_WARNING "aac_valid_context: scsi command corrupt\n")); aac_fib_complete(fibptr); - aac_fib_free(fibptr); return 0; } scsicmd->SCp.phase = AAC_OWNER_MIDLEVEL; @@ -331,7 +330,6 @@ static inline int aac_valid_context(struct scsi_cmnd *scsicmd, if (unlikely(!device || !scsi_device_online(device))) { dprintk((KERN_WARNING "aac_valid_context: scsi device corrupt\n")); aac_fib_complete(fibptr); - aac_fib_free(fibptr); return 0; } return 1; @@ -541,7 +539,6 @@ static void get_container_name_callback(void *context, struct fib * fibptr) scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; aac_fib_complete(fibptr); - aac_fib_free(fibptr); scsicmd->scsi_done(scsicmd); } @@ -557,7 +554,8 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd) dev = (struct aac_dev *)scsicmd->device->host->hostdata; - if (!(cmd_fibcontext = aac_fib_alloc(dev))) + cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd); + if (!cmd_fibcontext) return -ENOMEM; aac_fib_init(cmd_fibcontext); @@ -586,7 +584,6 @@ static int aac_get_container_name(struct scsi_cmnd * scsicmd) printk(KERN_WARNING "aac_get_container_name: aac_fib_send failed with status: %d.\n", status); aac_fib_complete(cmd_fibcontext); - aac_fib_free(cmd_fibcontext); return -1; } @@ -1024,7 +1021,6 @@ static void get_container_serial_callback(void *context, struct fib * fibptr) scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD; aac_fib_complete(fibptr); - aac_fib_free(fibptr); scsicmd->scsi_done(scsicmd); } @@ -1040,7 +1036,8 @@ static int aac_get_container_serial(struct scsi_cmnd * scsicmd) dev = (struct aac_dev *)scsicmd->device->host->hostdata; - if (!(cmd_fibcontext = aac_fib_alloc(dev))) + cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd); + if (!cmd_fibcontext) return -ENOMEM; aac_fib_init(cmd_fibcontext); @@ -1068,7 +1065,6 @@ static int aac_get_container_serial(struct scsi_cmnd * scsicmd) printk(KERN_WARNING "aac_get_container_serial: aac_fib_send failed with status: %d.\n", status); aac_fib_complete(cmd_fibcontext); - aac_fib_free(cmd_fibcontext); return -1; } @@ -1869,7 +1865,6 @@ static void io_callback(void *context, struct fib * fibptr) break; } aac_fib_complete(fibptr); - aac_fib_free(fibptr); scsicmd->scsi_done(scsicmd); } @@ -1954,7 +1949,8 @@ static int aac_read(struct scsi_cmnd * scsicmd) /* * Alocate and initialize a Fib */ - if (!(cmd_fibcontext = aac_fib_alloc(dev))) { + cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd); + if (!cmd_fibcontext) { printk(KERN_WARNING "aac_read: fib allocation failed\n"); return -1; } @@ -2051,7 +2047,8 @@ static int aac_write(struct scsi_cmnd * scsicmd) /* * Allocate and initialize a Fib then setup a BlockWrite command */ - if (!(cmd_fibcontext = aac_fib_alloc(dev))) { + cmd_fibcontext = aac_fib_alloc_tag(dev, scsicmd); + if (!cmd_fibcontext) { /* FIB temporarily unavailable,not catastrophic failure */ /*
[PATCH v2 4/9] aacraid: Fix memory leak in aac_fib_map_free
From: Raghava Aditya Renukuntaaac_fib_map_free() calls pci_free_consistent() without checking that dev->hw_fib_va is not NULL and dev->max_fib_size is not zero.If they are indeed NULL/0, this will result in a hang as pci_free_consistent() will attempt to invalidate cache for the entire 64-bit address space (which would take a very long time). Fixed by adding a check to make sure that dev->hw_fib_va and dev->max_fib_size are not NULL and 0 respectively. Changes in V2: None Signed-off-by: Raghava Aditya Renukunta --- drivers/scsi/aacraid/commsup.c | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index e9f6e70..55459b4 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -83,9 +83,12 @@ static int fib_map_alloc(struct aac_dev *dev) void aac_fib_map_free(struct aac_dev *dev) { - pci_free_consistent(dev->pdev, - dev->max_fib_size * (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB), - dev->hw_fib_va, dev->hw_fib_pa); + if (dev->hw_fib_va && dev->max_fib_size) { + pci_free_consistent(dev->pdev, + (dev->max_fib_size * + (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB)), + dev->hw_fib_va, dev->hw_fib_pa); + } dev->hw_fib_va = NULL; dev->hw_fib_pa = 0; } -- 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 v2 9/9] aacraid: Update driver version
From: Raghava Aditya RenukuntaUpdated diver version to 41052 Changes from V2: None Signed-off-by: Raghava Aditya Renukunta --- drivers/scsi/aacraid/aacraid.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index a440840..22130b3 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -62,7 +62,7 @@ enum { #definePMC_GLOBAL_INT_BIT0 0x0001 #ifndef AAC_DRIVER_BUILD -# define AAC_DRIVER_BUILD 41010 +# define AAC_DRIVER_BUILD 41052 # define AAC_DRIVER_BRANCH "-ms" #endif #define MAXIMUM_NUM_CONTAINERS 32 -- 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 v2 6/9] aacraid: Fundamental reset support for Series 7
From: Raghava Aditya RenukuntaSeries 7 does not support PCI hot reset used by EEH. Enabled fundamental reset only for Series 7 Changes in V2: None Signed-off-by: Raghava Aditya Renukunta --- drivers/scsi/aacraid/linit.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 6d79181..6944560 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -1135,6 +1135,12 @@ static int aac_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) u64 dmamask; extern int aac_sync_mode; + /* +* Only series 7 needs freset. +*/ +if (pdev->device == PMC_DEVICE_S7) + pdev->needs_freset = 1; + list_for_each_entry(aac, _devices, entry) { if (aac->id > unique_id) break; -- 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 v2 2/9] aacraid: Fix RRQ overload
From: Raghava Aditya RenukuntaThe driver utilizes an array of atomic variables to keep track of IO submissions to each vector. To submit an IO multiple threads iterate through the array to find a vector which has empty slots to send an IO. The reading and updating of the variable is not atomic, causing race conditions when a thread uses a full vector to submit an IO. Fixed by mapping each FIB to a vector, the submission path then uses said vector to submit IO thereby removing the possibly of a race condition.The vector assignment is started from 1 since vector 0 is reserved for the use of AIF management FIBS.If the number of MSIx vectors is 1 (MSI or INTx mode) then all the fibs are allocated to vector 0. Changes in V2: Created function aac_fib_vector_assign to assign vector numbers to fib and to prevent code duplication Signed-off-by: Raghava Aditya Renukunta --- drivers/scsi/aacraid/aacraid.h | 2 ++ drivers/scsi/aacraid/commsup.c | 28 drivers/scsi/aacraid/src.c | 30 +++--- 3 files changed, 37 insertions(+), 23 deletions(-) diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index f51f0a0..fff1306 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h @@ -944,6 +944,7 @@ struct fib { */ struct list_headfiblink; void*data; + u32 vector_no; struct hw_fib *hw_fib_va; /* Actual shared object */ dma_addr_t hw_fib_pa; /* physical address of hw_fib*/ }; @@ -2113,6 +2114,7 @@ static inline unsigned int cap_to_cyls(sector_t capacity, unsigned divisor) int aac_acquire_irq(struct aac_dev *dev); void aac_free_irq(struct aac_dev *dev); const char *aac_driverinfo(struct Scsi_Host *); +void aac_fib_vector_assign(struct aac_dev *dev); struct fib *aac_fib_alloc(struct aac_dev *dev); struct fib *aac_fib_alloc_tag(struct aac_dev *dev, struct scsi_cmnd *scmd); int aac_fib_setup(struct aac_dev *dev); diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index 6b286b3..e9f6e70 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c @@ -90,6 +90,28 @@ void aac_fib_map_free(struct aac_dev *dev) dev->hw_fib_pa = 0; } +void aac_fib_vector_assign(struct aac_dev *dev) +{ + u32 i = 0; + u32 vector = 1; + struct fib *fibptr = NULL; + + for (i = 0, fibptr = >fibs[i]; + i < (dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB); + i++, fibptr++) { + if ((dev->max_msix == 1) || + (i > ((dev->scsi_host_ptr->can_queue + AAC_NUM_MGT_FIB - 1) + - dev->vector_cap))) { + fibptr->vector_no = 0; + } else { + fibptr->vector_no = vector; + vector++; + if (vector == dev->max_msix) + vector = 1; + } + } +} + /** * aac_fib_setup - setup the fibs * @dev: Adapter to set up @@ -152,6 +174,12 @@ int aac_fib_setup(struct aac_dev * dev) hw_fib_pa = hw_fib_pa + dev->max_fib_size + sizeof(struct aac_fib_xporthdr); } + + /* +*Assign vector numbers to fibs +*/ + aac_fib_vector_assign(dev); + /* * Add the fib chain to the free list */ diff --git a/drivers/scsi/aacraid/src.c b/drivers/scsi/aacraid/src.c index 2aa34ea..bc0203f 100644 --- a/drivers/scsi/aacraid/src.c +++ b/drivers/scsi/aacraid/src.c @@ -156,8 +156,8 @@ static irqreturn_t aac_src_intr_message(int irq, void *dev_id) break; if (dev->msi_enabled && dev->max_msix > 1) atomic_dec(>rrq_outstanding[vector_no]); - aac_intr_normal(dev, handle-1, 0, isFastResponse, NULL); dev->host_rrq[index++] = 0; + aac_intr_normal(dev, handle-1, 0, isFastResponse, NULL); if (index == (vector_no + 1) * dev->vector_cap) index = vector_no * dev->vector_cap; dev->host_rrq_idx[vector_no] = index; @@ -452,36 +452,20 @@ static int aac_src_deliver_message(struct fib *fib) #endif u16 hdr_size = le16_to_cpu(fib->hw_fib_va->header.Size); + u16 vector_no; atomic_inc(>numpending); if (dev->msi_enabled && fib->hw_fib_va->header.Command != AifRequest && dev->max_msix > 1) { - u_int16_t vector_no, first_choice = 0x; - - vector_no = dev->fibs_pushed_no % dev->max_msix; - do { - vector_no += 1; - if
[PATCH V2 0/9] aacraid: Patchset for aacraid driver version 41052
This patchset includes the following changes (bug fixes and new feature support) specific to aacraid driver. V2: Removed aac_fib_free_tag function Setup relevant fib variables only in once Created aac_fib_vector_assign function Made EEH functions static Added character device status macros Changed location of aac->shutdown to prevent race condition Withdrew patch that disables device ID wild card binding Raghava Aditya Renukunta (9): [SCSI] aacraid: SCSI blk tag support [SCSI] aacraid: Fix RRQ overload [SCSI] aacraid: Added EEH support [SCSI] aacraid: Fix memory leak in aac_fib_map_free [SCSI] aacraid: Set correct msix count for EEH recovery [SCSI] aacraid: Fundamental reset support for Series 7 [SCSI] aacraid: Fix AIF triggered IOP_RESET [SCSI] aacraid: Fix character device re-initialization [SCSI] aacraid: Update driver version drivers/scsi/aacraid/aachba.c | 27 +++--- drivers/scsi/aacraid/aacraid.h | 13 ++- drivers/scsi/aacraid/comminit.c | 4 +- drivers/scsi/aacraid/commsup.c | 70 ++-- drivers/scsi/aacraid/dpcsup.c | 2 - drivers/scsi/aacraid/linit.c| 178 ++-- drivers/scsi/aacraid/src.c | 30 ++- 7 files changed, 267 insertions(+), 57 deletions(-) -- 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] ses: Fix problems with simple enclosures
On 9.12.2015 19:15, James Bottomley wrote: > On Wed, 2015-12-09 at 18:07 +0100, Tomas Henzl wrote: >> On 8.12.2015 18:00, James Bottomley wrote: >>> Simple enclosure implementations (mostly USB) are allowed to return only >>> page 8 to every diagnostic query. That really confuses our >>> implementation because we assume the return is the page we asked for and >>> end up doing incorrect offsets based on bogus information leading to >>> accesses outside of allocated ranges. Fix that by checking the page >>> code of the return and giving an error if it isn't the one we asked for. >>> This should fix reported bugs with USB storage by simply refusing to >>> attach to enclosures that behave like this. It's also good defensive >>> practise now that we're starting to see more USB enclosures. >> Ideally this patch also fixes all callers so they evaluate the return value >> from ses_recv_diag. That is missed in ses_enclosure_data_process >> and ses_get_page2_descriptor. > Well, it wouldn't be a bug fix and it's strictly not necessary. in > ses_intf_add() we won't attach if the initial retrieve of page 2 fails. > That means we already have an old copy. So if there's a failure in > ses_get_page2_descriptor() then we're just working from old data. > Essentially there's nothing else we could do (except perhaps log the > problem). You are right it is very unlikely that we read page2 with success in ses_intf_add and later page 8 is read instead in ses_get_page2_descriptor and rewrites the page 2. That means that we no longer have the old copy. Anyway its almost impossible and your patch per se is correct. Reviewed-by: Tomas HenzlTomas > > James > >> -tms >> >>> Reported-by: Andrea Gelmini >>> Cc: sta...@vger.kernel.org >>> Signed-off-by: James Bottomley >>> >>> --- >>> >>> diff --git a/drivers/scsi/ses.c b/drivers/scsi/ses.c >>> index dcb0d76..7d9cec5 100644 >>> --- a/drivers/scsi/ses.c >>> +++ b/drivers/scsi/ses.c >>> @@ -84,6 +84,7 @@ static void init_device_slot_control(unsigned char >>> *dest_desc, >>> static int ses_recv_diag(struct scsi_device *sdev, int page_code, >>> void *buf, int bufflen) >>> { >>> + int ret; >>> unsigned char cmd[] = { >>> RECEIVE_DIAGNOSTIC, >>> 1, /* Set PCV bit */ >>> @@ -92,9 +93,26 @@ static int ses_recv_diag(struct scsi_device *sdev, int >>> page_code, >>> bufflen & 0xff, >>> 0 >>> }; >>> + unsigned char recv_page_code; >>> >>> - return scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buf, bufflen, >>> + ret = scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buf, bufflen, >>> NULL, SES_TIMEOUT, SES_RETRIES, NULL); >>> + if (unlikely(!ret)) >>> + return ret; >>> + >>> + recv_page_code = ((unsigned char *)buf)[0]; >>> + >>> + if (likely(recv_page_code == page_code)) >>> + return ret; >>> + >>> + /* successful diagnostic but wrong page code. This happens to some >>> +* USB devices, just print a message and pretend there was an error */ >>> + >>> + sdev_printk(KERN_ERR, sdev, >>> + "Wrong diagnostic page; asked for %d got %u\n", >>> + page_code, recv_page_code); >>> + >>> + return -EINVAL; >>> } >>> >>> static int ses_send_diag(struct scsi_device *sdev, int page_code, >>> >>> >>> -- >>> 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 >> -- >> 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 >> > > > -- > 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 -- 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: [dm-devel] [PATCH 0/15] copy offload patches
On 12/10/2015 04:33 PM, Martin K. Petersen wrote: >> "Mikulas" == Mikulas Patockawrites: > > Mikulas, > > Mikulas> This patch series adds copy offload (the XCOPY command) to the > Mikulas> block layer, SCSI subsystems and device mapper. > > Now that the VFS stuff appears to stabilize I agree it's a good time to > revisit all this. I just merged the required VPD patches from Hannes so > those will be in 4.5. > > I have a bunch of changes to the SCSI code that I worked on over the > spring/summer based on a feedback from the array vendors after > discussions we started at LSF/MM. Generally speaking, their comments > didn't make things easier, nor prettier :( But your two bio approach is > a requirement to accommodate those needs (token-based copy) so I'll work > on consolidating your changes with mine. > > That said, we still need Mike Christie's patches to go in first. > > Mike: What's your status? I'm afraid I didn't get a chance to dig very > deep in your series since it coincided with me scrambling to sort out > SCSI for 4.4. Do you think there's a chance we could get your patches in > shape for 4.5? Is there an up-to-date tree I can look at? > It looks like my original mail did not make it due to an attachment. I just had 2 review comments left: 1. Originally, I had left REQ_FLUSH a flag. Christoph suggested to break it up into a op and flag: http://marc.info/?l=linux-scsi=144689113106515=2 I started this and messed up Was going to retry next week. 2. Start REQ_OP_READ off at non-zero to try and shake out code that was not converted. There are a several places where we assume reads are zero and writes are 1 for things like indexing in arrays (like blktrace's ddir_act or dm starts), passing into block functions (like nvme_alloc_request's call of blk_mq_alloc_request), and if/else's. I am not done fixing all of them and testing. Ok, 3 comments. One I gave myself: 3. Also, the btrfs patch is really large (1000 lines) because that code base is so large and there were so many places we passed around rw to through multiple functions. I wanted to try and break it up, so it would be easier for those guys to review. I uploaded a git tree here: https://github.com/mikechristie/kernel.git The patches are in the for-next-req-op. I made this over Jens's for-next branch in his linux-block tree. -- 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 0/3] Badblock tracking for gendisks
Hi Jens, Are you on-board with this approach? Any concerns with me carrying this through the nvdimm tree along with our other pending error-handling enabling? -- 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] hisi_sas: use platform_get_irq()
It is preferred that drivers use platform_get_irq() instead of irq_of_parse_and_map(), so replace. Signed-off-by: John Garrydiff --git a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c index 89ae31d..e907758 100644 --- a/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c +++ b/drivers/scsi/hisi_sas/hisi_sas_v1_hw.c @@ -1673,19 +1673,16 @@ static irq_handler_t fatal_interrupts[HISI_SAS_MAX_QUEUES] = { static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) { - struct device *dev = _hba->pdev->dev; - struct device_node *np = dev->of_node; + struct platform_device *pdev = hisi_hba->pdev; + struct device *dev = >dev; int i, j, irq, rc, idx; - if (!np) - return -ENOENT; - for (i = 0; i < hisi_hba->n_phy; i++) { struct hisi_sas_phy *phy = _hba->phy[i]; idx = i * HISI_SAS_PHY_INT_NR; for (j = 0; j < HISI_SAS_PHY_INT_NR; j++, idx++) { - irq = irq_of_parse_and_map(np, idx); + irq = platform_get_irq(pdev, idx); if (!irq) { dev_err(dev, "irq init: fail map phy interrupt %d\n", @@ -1706,7 +1703,7 @@ static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) idx = hisi_hba->n_phy * HISI_SAS_PHY_INT_NR; for (i = 0; i < hisi_hba->queue_count; i++, idx++) { - irq = irq_of_parse_and_map(np, idx); + irq = platform_get_irq(pdev, idx); if (!irq) { dev_err(dev, "irq init: could not map cq interrupt %d\n", idx); @@ -1724,7 +1721,7 @@ static int interrupt_init_v1_hw(struct hisi_hba *hisi_hba) idx = (hisi_hba->n_phy * HISI_SAS_PHY_INT_NR) + hisi_hba->queue_count; for (i = 0; i < HISI_SAS_FATAL_INT_NR; i++, idx++) { - irq = irq_of_parse_and_map(np, idx); + irq = platform_get_irq(pdev, idx); if (!irq) { dev_err(dev, "irq init: could not map fatal interrupt %d\n", idx); -- 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