Re: [PATCH v2] storvsc: add logging for error/warning messages

2015-12-10 Thread Martin K. Petersen
> "Long" == Long Li  writes:

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

2015-12-10 Thread Bart Van Assche

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

2015-12-10 Thread Mikulas Patocka
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

2015-12-10 Thread Mikulas Patocka
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

2015-12-10 Thread Mikulas Patocka
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

2015-12-10 Thread Mikulas Patocka
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

2015-12-10 Thread Mikulas Patocka
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()

2015-12-10 Thread Laura Abbott

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

2015-12-10 Thread Andy Shevchenko
On Thu, Dec 10, 2015 at 8:15 PM, Martin K. Petersen
 wrote:
>> "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

2015-12-10 Thread Martin K. Petersen
> "Andy" == Andy Shevchenko  writes:

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

2015-12-10 Thread Joe Perches
On Thu, 2015-12-10 at 14:13 -0500, Martin K. Petersen wrote:
> > > > > > "Andy" == Andy Shevchenko  writes:
> 
> 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()

2015-12-10 Thread Rob Herring
On Thu, Dec 10, 2015 at 9:02 AM, John Garry  wrote:
> 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

2015-12-10 Thread Martin K. Petersen
> "Matthew" == Matthew R Ochs  writes:

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

2015-12-10 Thread Bart Van Assche

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

2015-12-10 Thread Martin K. Petersen
> "Mikulas" == Mikulas Patocka  writes:

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

2015-12-10 Thread Lee Duncan
On 11/17/2015 03:20 PM, Martin K. Petersen wrote:
>> "Lee" == Lee Duncan  writes:
> 
> 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

2015-12-10 Thread K. Y. Srinivasan
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

2015-12-10 Thread K. Y. Srinivasan
The hv_fc_wwn_packet is exchanged over vmbus. Make the definition in Linux match
the Window's definition.

Signed-off-by: K. Y. Srinivasan 
Reviewed-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

2015-12-10 Thread Uma Krishnan
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

2015-12-10 Thread Finn Thain

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

2015-12-10 Thread Uma Krishnan
From: Manoj Kumar 

After 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

2015-12-10 Thread Uma Krishnan
From: Manoj Kumar 

If 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

2015-12-10 Thread Uma Krishnan
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

2015-12-10 Thread Uma Krishnan
From: Manoj Kumar 

The 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

2015-12-10 Thread Uma Krishnan
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)

2015-12-10 Thread Finn Thain

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

2015-12-10 Thread K. Y. Srinivasan
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. Srinivasan 
Reviewed-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

2015-12-10 Thread K. Y. Srinivasan
On the interrupt path, we repeatedly establish the pointer to the
storvsc_device. Fix this.

Signed-off-by: K. Y. Srinivasan 
Reviewed-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

2015-12-10 Thread Daniel Axtens
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()

2015-12-10 Thread K. Y. Srinivasan
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. Srinivasan 
Reviewed-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

2015-12-10 Thread Uma Krishnan
From: Manoj Kumar 

This 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

2015-12-10 Thread Mikulas Patocka
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. Petersen 
Signed-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

2015-12-10 Thread Bart Van Assche

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

2015-12-10 Thread Bart Van Assche

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

2015-12-10 Thread Bart Van Assche

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

2015-12-10 Thread Mikulas Patocka
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

2015-12-10 Thread Mikulas Patocka
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

2015-12-10 Thread Mikulas Patocka
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

2015-12-10 Thread Mikulas Patocka
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

2015-12-10 Thread Mikulas Patocka
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()

2015-12-10 Thread Martin K. Petersen
> "Dan" == Dan Carpenter  writes:

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

2015-12-10 Thread Bart Van Assche

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

2015-12-10 Thread Bart Van Assche

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

2015-12-10 Thread Bart Van Assche

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

2015-12-10 Thread Mikulas Patocka
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

2015-12-10 Thread Mikulas Patocka
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

2015-12-10 Thread Mikulas Patocka
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

2015-12-10 Thread Mikulas Patocka
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

2015-12-10 Thread Martin K. Petersen
> "Matthew" == Matthew R Ochs  writes:

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.

2015-12-10 Thread Martin K. Petersen
> "Josh" == Josh Boyer  writes:

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

2015-12-10 Thread Martin K. Petersen
> "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.

-- 
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

2015-12-10 Thread Bart Van Assche

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

2015-12-10 Thread Mikulas Patocka
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

2015-12-10 Thread Bart Van Assche

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

2015-12-10 Thread Raghava Aditya Renukunta
From: Raghava Aditya Renukunta 

Added 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

2015-12-10 Thread Raghava Aditya Renukunta
From: Raghava Aditya Renukunta 

During 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

2015-12-10 Thread Raghava Aditya Renukunta
From: Raghava Aditya Renukunta 

During 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

2015-12-10 Thread Raghava Aditya Renukunta
From: Raghava Aditya Renukunta 

while 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

2015-12-10 Thread Raghava Aditya Renukunta
From: Raghava Aditya Renukunta 

The 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

2015-12-10 Thread Raghava Aditya Renukunta
From: Raghava Aditya Renukunta 

aac_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

2015-12-10 Thread Raghava Aditya Renukunta
From: Raghava Aditya Renukunta 

Updated 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

2015-12-10 Thread Raghava Aditya Renukunta
From: Raghava Aditya Renukunta 

Series 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

2015-12-10 Thread Raghava Aditya Renukunta
From: Raghava Aditya Renukunta 

The 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

2015-12-10 Thread Raghava Aditya Renukunta
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

2015-12-10 Thread Tomas Henzl
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 Henzl 

Tomas

>
> 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

2015-12-10 Thread Mike Christie
On 12/10/2015 04:33 PM, Martin K. Petersen wrote:
>> "Mikulas" == Mikulas Patocka  writes:
> 
> 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

2015-12-10 Thread Dan Williams
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()

2015-12-10 Thread John Garry
It is preferred that drivers use platform_get_irq()
instead of irq_of_parse_and_map(), so replace.

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