Re: [PATCH] blk-throttle: fix infinite throttling caused by non-cascading timer wheel

2016-09-16 Thread Hou Tao

> Thanks for the patch. I can reproduce it. I am wondering that why are you
> doing so many checks. Can't we just check if throttle group is empty or
> not. If it is empty and slice has expired, then start a new slice. If
> throttle group is not empty, then we know slice has to be an active slice
> and should be extended (despite the fact that it might have expired
> because timer function got called later than we expected it to be).
Yes, only checking the empty status of bio queue is enough.

The check of dispatched ios and bytes was used to ensure the time slice
had not been used, but the logic is incorrect: even if the time slice
had been used, the extend of time slice is needed if the timer slacked.

> Can you please try following patch. It seems to resolve the issue for me.
It works for me.

--
To unsubscribe from this list: send the line "unsubscribe linux-block" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] blk-mq: account higher order dispatch

2016-09-16 Thread Omar Sandoval
On Thu, Sep 15, 2016 at 03:16:49PM -0600, Jens Axboe wrote:
> We currently account a '0' dispatch, and anything above that still falls
> below the range set by BLK_MQ_MAX_DISPATCH_ORDER. If we dispatch more,
> we don't account it.
> 
> Change the last bucket to be inclusive of anything above the range we
> track, and have the sysfs file reflect that by including a '+' in the
> output:
> 
> $ cat /sys/block/nvme0n1/mq/0/dispatched
>0  1006
>1  20229
>2  1
>4  0
>8  0
>   16  0
>   32+ 0
> 
> Signed-off-by: Jens Axboe 

Reviewed-by: Omar Sandoval 

-- 
Omar
--
To unsubscribe from this list: send the line "unsubscribe linux-block" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 4/7] blk-mq: register device instead of disk

2016-09-16 Thread Matias Bjørling
Enable devices without a gendisk instance to register itself with blk-mq
and expose the associated multi-queue sysfs entries.

Signed-off-by: Matias Bjørling 
---
 block/blk-mq-sysfs.c   | 17 +++--
 block/blk-sysfs.c  |  4 ++--
 drivers/md/dm-rq.c |  2 +-
 include/linux/blk-mq.h |  4 ++--
 4 files changed, 12 insertions(+), 15 deletions(-)

diff --git a/block/blk-mq-sysfs.c b/block/blk-mq-sysfs.c
index fe822aa..d998287 100644
--- a/block/blk-mq-sysfs.c
+++ b/block/blk-mq-sysfs.c
@@ -380,9 +380,8 @@ static int blk_mq_register_hctx(struct blk_mq_hw_ctx *hctx)
return ret;
 }
 
-static void __blk_mq_unregister_disk(struct gendisk *disk)
+static void __blk_mq_unregister_dev(struct device *dev, struct request_queue 
*q)
 {
-   struct request_queue *q = disk->queue;
struct blk_mq_hw_ctx *hctx;
struct blk_mq_ctx *ctx;
int i, j;
@@ -400,15 +399,15 @@ static void __blk_mq_unregister_disk(struct gendisk *disk)
kobject_del(&q->mq_kobj);
kobject_put(&q->mq_kobj);
 
-   kobject_put(&disk_to_dev(disk)->kobj);
+   kobject_put(&dev->kobj);
 
q->mq_sysfs_init_done = false;
 }
 
-void blk_mq_unregister_disk(struct gendisk *disk)
+void blk_mq_unregister_dev(struct device *dev, struct request_queue *q)
 {
blk_mq_disable_hotplug();
-   __blk_mq_unregister_disk(disk);
+   __blk_mq_unregister_dev(dev, q);
blk_mq_enable_hotplug();
 }
 
@@ -430,10 +429,8 @@ static void blk_mq_sysfs_init(struct request_queue *q)
}
 }
 
-int blk_mq_register_disk(struct gendisk *disk)
+int blk_mq_register_dev(struct device *dev, struct request_queue *q)
 {
-   struct device *dev = disk_to_dev(disk);
-   struct request_queue *q = disk->queue;
struct blk_mq_hw_ctx *hctx;
int ret, i;
 
@@ -454,7 +451,7 @@ int blk_mq_register_disk(struct gendisk *disk)
}
 
if (ret)
-   __blk_mq_unregister_disk(disk);
+   __blk_mq_unregister_dev(dev, q);
else
q->mq_sysfs_init_done = true;
 out:
@@ -462,7 +459,7 @@ out:
 
return ret;
 }
-EXPORT_SYMBOL_GPL(blk_mq_register_disk);
+EXPORT_SYMBOL_GPL(blk_mq_register_dev);
 
 void blk_mq_sysfs_unregister(struct request_queue *q)
 {
diff --git a/block/blk-sysfs.c b/block/blk-sysfs.c
index f87a7e7..9cc8d7c 100644
--- a/block/blk-sysfs.c
+++ b/block/blk-sysfs.c
@@ -704,7 +704,7 @@ int blk_register_queue(struct gendisk *disk)
kobject_uevent(&q->kobj, KOBJ_ADD);
 
if (q->mq_ops)
-   blk_mq_register_disk(disk);
+   blk_mq_register_dev(dev, q);
 
if (!q->request_fn)
return 0;
@@ -729,7 +729,7 @@ void blk_unregister_queue(struct gendisk *disk)
return;
 
if (q->mq_ops)
-   blk_mq_unregister_disk(disk);
+   blk_mq_unregister_dev(disk_to_dev(disk), q);
 
if (q->request_fn)
elv_unregister_queue(q);
diff --git a/drivers/md/dm-rq.c b/drivers/md/dm-rq.c
index 1ca7463..ee48230 100644
--- a/drivers/md/dm-rq.c
+++ b/drivers/md/dm-rq.c
@@ -955,7 +955,7 @@ int dm_mq_init_request_queue(struct mapped_device *md, 
struct dm_table *t)
dm_init_md_queue(md);
 
/* backfill 'mq' sysfs registration normally done in blk_register_queue 
*/
-   blk_mq_register_disk(md->disk);
+   blk_mq_register_dev(disk_to_dev(md->disk), q);
 
return 0;
 
diff --git a/include/linux/blk-mq.h b/include/linux/blk-mq.h
index e1544f0..f03a59d 100644
--- a/include/linux/blk-mq.h
+++ b/include/linux/blk-mq.h
@@ -179,8 +179,8 @@ enum {
 struct request_queue *blk_mq_init_queue(struct blk_mq_tag_set *);
 struct request_queue *blk_mq_init_allocated_queue(struct blk_mq_tag_set *set,
  struct request_queue *q);
-int blk_mq_register_disk(struct gendisk *);
-void blk_mq_unregister_disk(struct gendisk *);
+int blk_mq_register_dev(struct device *, struct request_queue *);
+void blk_mq_unregister_dev(struct device *, struct request_queue *);
 
 int blk_mq_alloc_tag_set(struct blk_mq_tag_set *set);
 void blk_mq_free_tag_set(struct blk_mq_tag_set *set);
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-block" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 7/7] lightnvm: propagate device_add() error code

2016-09-16 Thread Matias Bjørling
From: Arnd Bergmann 

device_add() may fail, and all callers are supposed to check the
return value, but one new user in lightnvm doesn't:

drivers/lightnvm/sysfs.c: In function 'nvm_sysfs_register_dev':
drivers/lightnvm/sysfs.c:184:2: error: ignoring return value of 'device_add',
  declared with attribute warn_unused_result [-Werror=unused-result]

This changes the caller to propagate any error codes, which avoids
the warning.

Signed-off-by: Arnd Bergmann 
Fixes: 38c9e260b9f9 ("lightnvm: expose device geometry through sysfs")
Signed-off-by: Matias Bjørling 
---
 drivers/lightnvm/lightnvm.h | 2 +-
 drivers/lightnvm/sysfs.c| 9 ++---
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/lightnvm/lightnvm.h b/drivers/lightnvm/lightnvm.h
index 93f1aac..305c181 100644
--- a/drivers/lightnvm/lightnvm.h
+++ b/drivers/lightnvm/lightnvm.h
@@ -24,7 +24,7 @@
 #include 
 
 /* core -> sysfs.c */
-int nvm_sysfs_register_dev(struct nvm_dev *);
+int __must_check nvm_sysfs_register_dev(struct nvm_dev *);
 void nvm_sysfs_unregister_dev(struct nvm_dev *);
 int nvm_sysfs_register(void);
 void nvm_sysfs_unregister(void);
diff --git a/drivers/lightnvm/sysfs.c b/drivers/lightnvm/sysfs.c
index 72ad089..0338c27 100644
--- a/drivers/lightnvm/sysfs.c
+++ b/drivers/lightnvm/sysfs.c
@@ -174,6 +174,8 @@ static struct device_type nvm_type = {
 
 int nvm_sysfs_register_dev(struct nvm_dev *dev)
 {
+   int ret;
+
if (!dev->parent_dev)
return 0;
 
@@ -181,11 +183,12 @@ int nvm_sysfs_register_dev(struct nvm_dev *dev)
dev_set_name(&dev->dev, "%s", dev->name);
dev->dev.type = &nvm_type;
device_initialize(&dev->dev);
-   device_add(&dev->dev);
+   ret = device_add(&dev->dev);
 
-   blk_mq_register_dev(&dev->dev, dev->q);
+   if (!ret)
+   blk_mq_register_dev(&dev->dev, dev->q);
 
-   return 0;
+   return ret;
 }
 
 void nvm_sysfs_unregister_dev(struct nvm_dev *dev)
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-block" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/7] null_blk: refactor to support non-gendisk devices

2016-09-16 Thread Matias Bjørling
With LightNVM enabled devices, the gendisk structure is not exposed
to the user. This hides the device driver specific sysfs entries, and
prevents binding of LightNVM geometry information to the device.

Refactor the device registration process, so that gendisk and
non-gendisk devices are easily managed.

Signed-off-by: Matias Bjørling 
---
 drivers/block/null_blk.c | 110 ++-
 1 file changed, 61 insertions(+), 49 deletions(-)

diff --git a/drivers/block/null_blk.c b/drivers/block/null_blk.c
index 75a7f88..895867a 100644
--- a/drivers/block/null_blk.c
+++ b/drivers/block/null_blk.c
@@ -414,23 +414,6 @@ static void cleanup_queues(struct nullb *nullb)
kfree(nullb->queues);
 }
 
-static void null_del_dev(struct nullb *nullb)
-{
-   list_del_init(&nullb->list);
-
-   if (use_lightnvm)
-   nvm_unregister(nullb->disk_name);
-   else
-   del_gendisk(nullb->disk);
-   blk_cleanup_queue(nullb->q);
-   if (queue_mode == NULL_Q_MQ)
-   blk_mq_free_tag_set(&nullb->tag_set);
-   if (!use_lightnvm)
-   put_disk(nullb->disk);
-   cleanup_queues(nullb);
-   kfree(nullb);
-}
-
 #ifdef CONFIG_NVM
 
 static void null_lnvm_end_io(struct request *rq, int error)
@@ -564,10 +547,41 @@ static struct nvm_dev_ops null_lnvm_dev_ops = {
/* Simulate nvme protocol restriction */
.max_phys_sect  = 64,
 };
+
+static int null_nvm_register(struct nullb *nullb)
+{
+   return nvm_register(nullb->q, nullb->disk_name, &null_lnvm_dev_ops);
+}
+
+static void null_nvm_unregister(struct nullb *nullb)
+{
+   nvm_unregister(nullb->disk_name);
+}
 #else
-static struct nvm_dev_ops null_lnvm_dev_ops;
+static int null_nvm_register(struct nullb *nullb)
+{
+   return -EINVAL;
+}
+static void null_nvm_unregister(struct nullb *nullb) {}
 #endif /* CONFIG_NVM */
 
+static void null_del_dev(struct nullb *nullb)
+{
+   list_del_init(&nullb->list);
+
+   if (use_lightnvm)
+   null_nvm_unregister(nullb);
+   else
+   del_gendisk(nullb->disk);
+   blk_cleanup_queue(nullb->q);
+   if (queue_mode == NULL_Q_MQ)
+   blk_mq_free_tag_set(&nullb->tag_set);
+   if (!use_lightnvm)
+   put_disk(nullb->disk);
+   cleanup_queues(nullb);
+   kfree(nullb);
+}
+
 static int null_open(struct block_device *bdev, fmode_t mode)
 {
return 0;
@@ -640,11 +654,32 @@ static int init_driver_queues(struct nullb *nullb)
return 0;
 }
 
-static int null_add_dev(void)
+static int null_gendisk_register(struct nullb *nullb)
 {
struct gendisk *disk;
-   struct nullb *nullb;
sector_t size;
+
+   disk = nullb->disk = alloc_disk_node(1, home_node);
+   if (!disk)
+   return -ENOMEM;
+   size = gb * 1024 * 1024 * 1024ULL;
+   set_capacity(disk, size >> 9);
+
+   disk->flags |= GENHD_FL_EXT_DEVT | GENHD_FL_SUPPRESS_PARTITION_INFO;
+   disk->major = null_major;
+   disk->first_minor   = nullb->index;
+   disk->fops  = &null_fops;
+   disk->private_data  = nullb;
+   disk->queue = nullb->q;
+   strncpy(disk->disk_name, nullb->disk_name, DISK_NAME_LEN);
+
+   add_disk(disk);
+   return 0;
+}
+
+static int null_add_dev(void)
+{
+   struct nullb *nullb;
int rv;
 
nullb = kzalloc_node(sizeof(*nullb), GFP_KERNEL, home_node);
@@ -716,42 +751,19 @@ static int null_add_dev(void)
 
sprintf(nullb->disk_name, "nullb%d", nullb->index);
 
-   if (use_lightnvm) {
-   rv = nvm_register(nullb->q, nullb->disk_name,
-   &null_lnvm_dev_ops);
-   if (rv)
-   goto out_cleanup_blk_queue;
-   goto done;
-   }
+   if (use_lightnvm)
+   rv = null_nvm_register(nullb);
+   else
+   rv = null_gendisk_register(nullb);
 
-   disk = nullb->disk = alloc_disk_node(1, home_node);
-   if (!disk) {
-   rv = -ENOMEM;
-   goto out_cleanup_lightnvm;
-   }
-   size = gb * 1024 * 1024 * 1024ULL;
-   set_capacity(disk, size >> 9);
+   if (rv)
+   goto out_cleanup_blk_queue;
 
-   disk->flags |= GENHD_FL_EXT_DEVT | GENHD_FL_SUPPRESS_PARTITION_INFO;
-   disk->major = null_major;
-   disk->first_minor   = nullb->index;
-   disk->fops  = &null_fops;
-   disk->private_data  = nullb;
-   disk->queue = nullb->q;
-   strncpy(disk->disk_name, nullb->disk_name, DISK_NAME_LEN);
-
-   add_disk(disk);
-
-done:
mutex_lock(&lock);
list_add_tail(&nullb->list, &nullb_list);
mutex_unlock(&lock);
 
return 0;
-
-out_cleanup_lightnvm:
-   if (use_lightnvm)
-   nvm_unregister(nullb->disk_name);
 out_cleanup_blk_queue:
bl

[PATCH 6/7] lightnvm: expose device geometry through sysfs

2016-09-16 Thread Matias Bjørling
From: "Simon A. F. Lund" 

For a host to access an Open-Channel SSD, it has to know its geometry,
so that it writes and reads at the appropriate device bounds.

Currently, the geometry information is kept within the kernel, and not
exported to user-space for consumption. This patch exposes the
configuration through sysfs and enables user-space libraries, such as
liblightnvm, to use the sysfs implementation to get the geometry of an
Open-Channel SSD.

The sysfs entries are stored within the device hierarchy, and can be
found using the "lightnvm" device type.

An example configuration looks like this:

/sys/class/nvme/
└── nvme0n1
   ├── capabilities: 3
   ├── device_mode: 1
   ├── erase_max: 100
   ├── erase_typ: 100
   ├── flash_media_type: 0
   ├── media_capabilities: 0x0001
   ├── media_type: 0
   ├── multiplane: 0x00010101
   ├── num_blocks: 1022
   ├── num_channels: 1
   ├── num_luns: 4
   ├── num_pages: 64
   ├── num_planes: 1
   ├── page_size: 4096
   ├── prog_max: 10
   ├── prog_typ: 10
   ├── read_max: 1
   ├── read_typ: 1
   ├── sector_oob_size: 0
   ├── sector_size: 4096
   ├── media_manager: gennvm
   ├── ppa_format: 0x380830082808001010102008
   ├── vendor_opcode: 0
   ├── max_phys_secs: 64
   └── version: 1

Signed-off-by: Simon A. F. Lund 
Signed-off-by: Matias Bjørling 
---
 drivers/lightnvm/Makefile|   2 +-
 drivers/lightnvm/core.c  |  20 +++--
 drivers/lightnvm/lightnvm.h  |  35 
 drivers/lightnvm/sysfs.c | 195 +++
 drivers/nvme/host/core.c |  13 +--
 drivers/nvme/host/lightnvm.c |   9 +-
 drivers/nvme/host/nvme.h |  18 +++-
 include/linux/lightnvm.h |   3 +
 8 files changed, 278 insertions(+), 17 deletions(-)
 create mode 100644 drivers/lightnvm/lightnvm.h
 create mode 100644 drivers/lightnvm/sysfs.c

diff --git a/drivers/lightnvm/Makefile b/drivers/lightnvm/Makefile
index a7a0a22..1f6b652 100644
--- a/drivers/lightnvm/Makefile
+++ b/drivers/lightnvm/Makefile
@@ -2,6 +2,6 @@
 # Makefile for Open-Channel SSDs.
 #
 
-obj-$(CONFIG_NVM)  := core.o sysblk.o
+obj-$(CONFIG_NVM)  := core.o sysblk.o sysfs.o
 obj-$(CONFIG_NVM_GENNVM)   += gennvm.o
 obj-$(CONFIG_NVM_RRPC) += rrpc.o
diff --git a/drivers/lightnvm/core.c b/drivers/lightnvm/core.c
index a99b59d..a2393e1 100644
--- a/drivers/lightnvm/core.c
+++ b/drivers/lightnvm/core.c
@@ -27,6 +27,8 @@
 #include 
 #include 
 
+#include "lightnvm.h"
+
 static LIST_HEAD(nvm_tgt_types);
 static DECLARE_RWSEM(nvm_tgtt_lock);
 static LIST_HEAD(nvm_mgrs);
@@ -598,15 +600,19 @@ static void nvm_free_mgr(struct nvm_dev *dev)
dev->mt = NULL;
 }
 
-static void nvm_free(struct nvm_dev *dev)
+void nvm_free(struct nvm_dev *dev)
 {
if (!dev)
return;
 
nvm_free_mgr(dev);
 
+   if (dev->dma_pool)
+   dev->ops->destroy_dma_pool(dev->dma_pool);
+
kfree(dev->lptbl);
kfree(dev->lun_map);
+   kfree(dev);
 }
 
 static int nvm_init(struct nvm_dev *dev)
@@ -653,11 +659,7 @@ err:
 
 static void nvm_exit(struct nvm_dev *dev)
 {
-   if (dev->dma_pool)
-   dev->ops->destroy_dma_pool(dev->dma_pool);
-   nvm_free(dev);
-
-   pr_info("nvm: successfully unloaded\n");
+   nvm_sysfs_unregister_dev(dev);
 }
 
 struct nvm_dev *nvm_alloc_dev(int node)
@@ -689,6 +691,10 @@ int nvm_register(struct nvm_dev *dev)
}
}
 
+   ret = nvm_sysfs_register_dev(dev);
+   if (ret)
+   goto err_ppalist;
+
if (dev->identity.cap & NVM_ID_DCAP_BBLKMGMT) {
ret = nvm_get_sysblock(dev, &dev->sb);
if (!ret)
@@ -705,6 +711,8 @@ int nvm_register(struct nvm_dev *dev)
up_write(&nvm_lock);
 
return 0;
+err_ppalist:
+   dev->ops->destroy_dma_pool(dev->dma_pool);
 err_init:
kfree(dev->lun_map);
return ret;
diff --git a/drivers/lightnvm/lightnvm.h b/drivers/lightnvm/lightnvm.h
new file mode 100644
index 000..93f1aac
--- /dev/null
+++ b/drivers/lightnvm/lightnvm.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2016 CNEX Labs. All rights reserved.
+ * Initial release: Matias Bjorling 
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version
+ * 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139,
+ * USA.
+ *
+ */
+
+#ifndef LIGHTNVM_H
+#define LIGHTNVM_H
+
+#include 
+
+/* core -> sysfs.c */
+int nvm_sysfs_register_dev(struct nvm_dev *)

[PATCH 5/7] lightnvm: control life of nvm_dev in driver

2016-09-16 Thread Matias Bjørling
LightNVM compatible device drivers does not have a method to expose
LightNVM specific sysfs entries.

To enable LightNVM sysfs entries to be exposed, lightnvm device
drivers require a struct device to attach it to. To allow both the
actual device driver and lightnvm sysfs entries to coexist, the device
driver tracks the lifetime of the nvm_dev structure.

This patch refactors NVMe and null_blk to handle the lifetime of struct
nvm_dev, which eliminates the need for struct gendisk when a lightnvm
compatible device is provided.

Signed-off-by: Matias Bjørling 
---
 drivers/block/null_blk.c | 22 --
 drivers/lightnvm/core.c  | 35 ---
 drivers/nvme/host/core.c | 36 +++-
 drivers/nvme/host/lightnvm.c | 31 ---
 drivers/nvme/host/nvme.h | 12 +++-
 include/linux/lightnvm.h | 15 +--
 6 files changed, 83 insertions(+), 68 deletions(-)

diff --git a/drivers/block/null_blk.c b/drivers/block/null_blk.c
index 895867a..91e1de8 100644
--- a/drivers/block/null_blk.c
+++ b/drivers/block/null_blk.c
@@ -34,6 +34,7 @@ struct nullb {
unsigned int index;
struct request_queue *q;
struct gendisk *disk;
+   struct nvm_dev *ndev;
struct blk_mq_tag_set tag_set;
struct hrtimer timer;
unsigned int queue_depth;
@@ -550,12 +551,29 @@ static struct nvm_dev_ops null_lnvm_dev_ops = {
 
 static int null_nvm_register(struct nullb *nullb)
 {
-   return nvm_register(nullb->q, nullb->disk_name, &null_lnvm_dev_ops);
+   struct nvm_dev *dev;
+   int rv;
+
+   dev = nvm_alloc_dev(0);
+   if (!dev)
+   return -ENOMEM;
+
+   dev->q = nullb->q;
+   memcpy(dev->name, nullb->disk_name, DISK_NAME_LEN);
+   dev->ops = &null_lnvm_dev_ops;
+
+   rv = nvm_register(dev);
+   if (rv) {
+   kfree(dev);
+   return rv;
+   }
+   nullb->ndev = dev;
+   return 0;
 }
 
 static void null_nvm_unregister(struct nullb *nullb)
 {
-   nvm_unregister(nullb->disk_name);
+   nvm_unregister(nullb->ndev);
 }
 #else
 static int null_nvm_register(struct nullb *nullb)
diff --git a/drivers/lightnvm/core.c b/drivers/lightnvm/core.c
index 25c5df9..a99b59d 100644
--- a/drivers/lightnvm/core.c
+++ b/drivers/lightnvm/core.c
@@ -660,23 +660,16 @@ static void nvm_exit(struct nvm_dev *dev)
pr_info("nvm: successfully unloaded\n");
 }
 
-int nvm_register(struct request_queue *q, char *disk_name,
-   struct nvm_dev_ops *ops)
+struct nvm_dev *nvm_alloc_dev(int node)
+{
+   return kzalloc_node(sizeof(struct nvm_dev), GFP_KERNEL, node);
+}
+EXPORT_SYMBOL(nvm_alloc_dev);
+
+int nvm_register(struct nvm_dev *dev)
 {
-   struct nvm_dev *dev;
int ret;
 
-   if (!ops->identity)
-   return -EINVAL;
-
-   dev = kzalloc(sizeof(struct nvm_dev), GFP_KERNEL);
-   if (!dev)
-   return -ENOMEM;
-
-   dev->q = q;
-   dev->ops = ops;
-   strncpy(dev->name, disk_name, DISK_NAME_LEN);
-
ret = nvm_init(dev);
if (ret)
goto err_init;
@@ -714,29 +707,17 @@ int nvm_register(struct request_queue *q, char *disk_name,
return 0;
 err_init:
kfree(dev->lun_map);
-   kfree(dev);
return ret;
 }
 EXPORT_SYMBOL(nvm_register);
 
-void nvm_unregister(char *disk_name)
+void nvm_unregister(struct nvm_dev *dev)
 {
-   struct nvm_dev *dev;
-
down_write(&nvm_lock);
-   dev = nvm_find_nvm_dev(disk_name);
-   if (!dev) {
-   pr_err("nvm: could not find device %s to unregister\n",
-   disk_name);
-   up_write(&nvm_lock);
-   return;
-   }
-
list_del(&dev->devices);
up_write(&nvm_lock);
 
nvm_exit(dev);
-   kfree(dev);
 }
 EXPORT_SYMBOL(nvm_unregister);
 
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 2c3da33..3c707d8 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -156,12 +156,14 @@ static void nvme_free_ns(struct kref *kref)
 {
struct nvme_ns *ns = container_of(kref, struct nvme_ns, kref);
 
-   if (ns->type == NVME_NS_LIGHTNVM)
-   nvme_nvm_unregister(ns->queue, ns->disk->disk_name);
+   if (ns->ndev)
+   nvme_nvm_unregister(ns);
 
-   spin_lock(&dev_list_lock);
-   ns->disk->private_data = NULL;
-   spin_unlock(&dev_list_lock);
+   if (ns->disk) {
+   spin_lock(&dev_list_lock);
+   ns->disk->private_data = NULL;
+   spin_unlock(&dev_list_lock);
+   }
 
put_disk(ns->disk);
ida_simple_remove(&ns->ctrl->ns_ida, ns->instance);
@@ -891,8 +893,7 @@ static void nvme_config_discard(struct nvme_ns *ns)
 static int nvme_revalidate_ns(struct nvme_ns *ns, struct nvme_id_

[PATCH 2/7] nvme: refactor namespaces to support non-gendisk devices

2016-09-16 Thread Matias Bjørling
With LightNVM enabled namespaces, the gendisk structure is not exposed
to the user. This prevents LightNVM users from accessing the NVMe device
driver specific sysfs entries, and LightNVM namespace geometry.

Refactor the revalidation process, so that a namespace, instead of a
gendisk, is revalidated. This later allows patches to wire up the
sysfs entries up to a non-gendisk namespace.

Signed-off-by: Matias Bjørling 
---
 drivers/lightnvm/core.c  |   2 +
 drivers/nvme/host/core.c | 116 +++
 drivers/nvme/host/lightnvm.c |   5 +-
 3 files changed, 79 insertions(+), 44 deletions(-)

diff --git a/drivers/lightnvm/core.c b/drivers/lightnvm/core.c
index 9ebd2cf..25c5df9 100644
--- a/drivers/lightnvm/core.c
+++ b/drivers/lightnvm/core.c
@@ -581,6 +581,8 @@ static int nvm_core_init(struct nvm_dev *dev)
mutex_init(&dev->mlock);
spin_lock_init(&dev->lock);
 
+   blk_queue_logical_block_size(dev->q, dev->sec_size);
+
return 0;
 err_fmtype:
kfree(dev->lun_map);
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 2feacc7..2c3da33 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -888,42 +888,33 @@ static void nvme_config_discard(struct nvme_ns *ns)
queue_flag_set_unlocked(QUEUE_FLAG_DISCARD, ns->queue);
 }
 
-static int nvme_revalidate_disk(struct gendisk *disk)
+static int nvme_revalidate_ns(struct nvme_ns *ns, struct nvme_id_ns **id)
 {
-   struct nvme_ns *ns = disk->private_data;
-   struct nvme_id_ns *id;
-   u8 lbaf, pi_type;
-   u16 old_ms;
-   unsigned short bs;
-
-   if (test_bit(NVME_NS_DEAD, &ns->flags)) {
-   set_capacity(disk, 0);
-   return -ENODEV;
-   }
-   if (nvme_identify_ns(ns->ctrl, ns->ns_id, &id)) {
+   if (nvme_identify_ns(ns->ctrl, ns->ns_id, id)) {
dev_warn(disk_to_dev(ns->disk), "%s: Identify failure\n",
__func__);
return -ENODEV;
}
-   if (id->ncap == 0) {
-   kfree(id);
-   return -ENODEV;
-   }
 
-   if (nvme_nvm_ns_supported(ns, id) && ns->type != NVME_NS_LIGHTNVM) {
-   if (nvme_nvm_register(ns->queue, disk->disk_name)) {
-   dev_warn(disk_to_dev(ns->disk),
-   "%s: LightNVM init failure\n", __func__);
-   kfree(id);
-   return -ENODEV;
-   }
-   ns->type = NVME_NS_LIGHTNVM;
+   if ((*id)->ncap == 0) {
+   kfree(*id);
+   return -ENODEV;
}
 
if (ns->ctrl->vs >= NVME_VS(1, 1))
-   memcpy(ns->eui, id->eui64, sizeof(ns->eui));
+   memcpy(ns->eui, (*id)->eui64, sizeof(ns->eui));
if (ns->ctrl->vs >= NVME_VS(1, 2))
-   memcpy(ns->uuid, id->nguid, sizeof(ns->uuid));
+   memcpy(ns->uuid, (*id)->nguid, sizeof(ns->uuid));
+
+   return 0;
+}
+
+static void __nvme_revalidate_disk(struct gendisk *disk, struct nvme_id_ns *id)
+{
+   struct nvme_ns *ns = disk->private_data;
+   u8 lbaf, pi_type;
+   u16 old_ms;
+   unsigned short bs;
 
old_ms = ns->ms;
lbaf = id->flbas & NVME_NS_FLBAS_LBA_MASK;
@@ -962,8 +953,26 @@ static int nvme_revalidate_disk(struct gendisk *disk)
if (ns->ctrl->oncs & NVME_CTRL_ONCS_DSM)
nvme_config_discard(ns);
blk_mq_unfreeze_queue(disk->queue);
+}
 
+static int nvme_revalidate_disk(struct gendisk *disk)
+{
+   struct nvme_ns *ns = disk->private_data;
+   struct nvme_id_ns *id = NULL;
+   int ret;
+
+   if (test_bit(NVME_NS_DEAD, &ns->flags)) {
+   set_capacity(disk, 0);
+   return -ENODEV;
+   }
+
+   ret = nvme_revalidate_ns(ns, &id);
+   if (ret)
+   return ret;
+
+   __nvme_revalidate_disk(disk, id);
kfree(id);
+
return 0;
 }
 
@@ -1642,6 +1651,8 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, 
unsigned nsid)
 {
struct nvme_ns *ns;
struct gendisk *disk;
+   struct nvme_id_ns *id;
+   char disk_name[DISK_NAME_LEN];
int node = dev_to_node(ctrl->dev);
 
ns = kzalloc_node(sizeof(*ns), GFP_KERNEL, node);
@@ -1659,33 +1670,54 @@ static void nvme_alloc_ns(struct nvme_ctrl *ctrl, 
unsigned nsid)
ns->queue->queuedata = ns;
ns->ctrl = ctrl;
 
-   disk = alloc_disk_node(0, node);
-   if (!disk)
-   goto out_free_queue;
-
kref_init(&ns->kref);
ns->ns_id = nsid;
-   ns->disk = disk;
ns->lba_shift = 9; /* set to a default value for 512 until disk is 
validated */
 
-
blk_queue_logical_block_size(ns->queue, 1 << ns->lba_shift);
nvme_set_queue_limits(ctrl, ns->queue);
 
-   disk->fops = &nvme_fops;
-   disk->private_data = ns;
-   disk->queue = ns->queue;
-   disk->flags = GENHD_FL_EXT_DEV

[PATCH 1/7] lightnvm: NVM should depend on HAS_DMA

2016-09-16 Thread Matias Bjørling
From: Geert Uytterhoeven 

If NO_DMA=y:

drivers/built-in.o: In function `nvme_nvm_dev_dma_free':
lightnvm.c:(.text+0x23df1a): undefined reference to `dma_pool_free'
drivers/built-in.o: In function `nvme_nvm_dev_dma_alloc':
lightnvm.c:(.text+0x23df38): undefined reference to `dma_pool_alloc'
drivers/built-in.o: In function `nvme_nvm_destroy_dma_pool':
lightnvm.c:(.text+0x23df4c): undefined reference to `dma_pool_destroy'
drivers/built-in.o: In function `nvme_nvm_create_dma_pool':
lightnvm.c:(.text+0x23df7e): undefined reference to `dma_pool_create'

and

ERROR: "dma_pool_destroy" [drivers/nvme/host/nvme-core.ko] undefined!
ERROR: "dma_pool_free" [drivers/nvme/host/nvme-core.ko] undefined!
ERROR: "dma_pool_alloc" [drivers/nvme/host/nvme-core.ko] undefined!
ERROR: "dma_pool_create" [drivers/nvme/host/nvme-core.ko] undefined!

Signed-off-by: Geert Uytterhoeven 
Signed-off-by: Matias Bjørling 
---
 drivers/lightnvm/Kconfig | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/lightnvm/Kconfig b/drivers/lightnvm/Kconfig
index 61c68a1..2f5d5f4 100644
--- a/drivers/lightnvm/Kconfig
+++ b/drivers/lightnvm/Kconfig
@@ -4,7 +4,7 @@
 
 menuconfig NVM
bool "Open-Channel SSD target support"
-   depends on BLOCK
+   depends on BLOCK && HAS_DMA
help
  Say Y here to get to enable Open-channel SSDs.
 
-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-block" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[GIT PULL 0/7] LightNVM pull request for 4.9

2016-09-16 Thread Matias Bjørling
Hi Jens,

A couple of patches for 4.9. We are preparing the pblk target for
upstream, but it will have to wait for at least a cycle before it is
ready.

Geert and Arnd sent two fixes. One check for DMA and another for missing
a device_add check.

Simon added sysfs support to LightNVM. It allows the user to inspect the
geometry of a device through sysfs. As NVMe device driver integrates
with blk-mq, it also exposes the blk-mq sysfs structure.

I added a couple of plumbing patches to enable sysfs. It mainly
refactors nvme and null_blk to take control over nvm_dev and replaces
the gendisk parameter in blk_mq_(un)register_disk() with device and the
associated request queue.

Please pick up.

The patches are available here:

  https://github.com/OpenChannelSSD/linux.git for-jens

Thank you,
Matias

Arnd Bergmann (1):
  lightnvm: propagate device_add() error code

Geert Uytterhoeven (1):
  lightnvm: NVM should depend on HAS_DMA

Matias Bjørling (4):
  nvme: refactor namespaces to support non-gendisk devices
  null_blk: refactor to support non-gendisk devices
  blk-mq: register device instead of disk
  lightnvm: control life of nvm_dev in driver

Simon A. F. Lund (1):
  lightnvm: expose device geometry through sysfs

 block/blk-mq-sysfs.c |  17 ++--
 block/blk-sysfs.c|   4 +-
 drivers/block/null_blk.c | 128 +---
 drivers/lightnvm/Kconfig |   2 +-
 drivers/lightnvm/Makefile|   2 +-
 drivers/lightnvm/core.c  |  55 +---
 drivers/lightnvm/lightnvm.h  |  35 
 drivers/lightnvm/sysfs.c | 198 +++
 drivers/md/dm-rq.c   |   2 +-
 drivers/nvme/host/core.c | 149 +++-
 drivers/nvme/host/lightnvm.c |  33 ++--
 drivers/nvme/host/nvme.h |  26 --
 include/linux/blk-mq.h   |   4 +-
 include/linux/lightnvm.h |  18 ++--
 14 files changed, 498 insertions(+), 175 deletions(-)
 create mode 100644 drivers/lightnvm/lightnvm.h
 create mode 100644 drivers/lightnvm/sysfs.c

-- 
2.1.4

--
To unsubscribe from this list: send the line "unsubscribe linux-block" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCHv3 29/41] ext4: make ext4_mpage_readpages() hugepage-aware

2016-09-16 Thread Kirill A. Shutemov
On Thu, Sep 15, 2016 at 06:27:10AM -0600, Andreas Dilger wrote:
> On Sep 15, 2016, at 5:55 AM, Kirill A. Shutemov 
>  wrote:
> > 
> > This patch modifies ext4_mpage_readpages() to deal with huge pages.
> > 
> > We read out 2M at once, so we have to alloc (HPAGE_PMD_NR *
> > blocks_per_page) sector_t for that. I'm not entirely happy with kmalloc
> > in this codepath, but don't see any other option.
> 
> If you're reading 2MB from disk (possibly from disjoint blocks with seeks
> in between) I don't think that the kmalloc() is going to be the limiting
> performance factor.  If you are concerned about the size of the kmalloc()
> causing failures when pages are fragmented (it can be 16KB for 1KB blocks
> with 4KB pages), then using ext4_kvmalloc() to fall back to vmalloc() in
> case kmalloc() fails.  It shouldn't fail often for 16KB allocations,
> but it could in theory.

Good point. Will use ext4_kvmalloc().

> I also notice that ext4_kvmalloc() should probably use unlikely() for
> the failure case, so that the uncommon vmalloc() fallback is out-of-line
> in this more important codepath.  The only other callers are during mount,
> so a branch misprediction is not critical.

I agree. But it's out-of-scope for the patchset.

-- 
 Kirill A. Shutemov
--
To unsubscribe from this list: send the line "unsubscribe linux-block" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCHv3 29/41] ext4: make ext4_mpage_readpages() hugepage-aware

2016-09-16 Thread Kirill A. Shutemov
On Thu, Sep 15, 2016 at 02:55:11PM +0300, Kirill A. Shutemov wrote:
> This patch modifies ext4_mpage_readpages() to deal with huge pages.
> 
> We read out 2M at once, so we have to alloc (HPAGE_PMD_NR *
> blocks_per_page) sector_t for that. I'm not entirely happy with kmalloc
> in this codepath, but don't see any other option.
> 
> Signed-off-by: Kirill A. Shutemov 

0-DAY reported this:

compiler: powerpc64-linux-gnu-gcc (Debian 5.4.0-6) 5.4.0 20160609
reproduce:
wget 
https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross
 -O ~/bin/make.cro
+ss
chmod +x ~/bin/make.cross
git checkout d8bfe8f327288810a9a099b15f3c89a834d419a4
# save the attached .config to linux build tree
make.cross ARCH=powerpc

All errors (new ones prefixed by >>):

   In file included from include/linux/linkage.h:4:0,
from include/linux/kernel.h:6,
from fs/ext4/readpage.c:30:
   fs/ext4/readpage.c: In function 'ext4_mpage_readpages':
>> include/linux/compiler.h:491:38: error: call to '__compiletime_assert_144' 
>> declared with attribute error:
+BUILD_BUG_ON failed: BIO_MAX_PAGES < HPAGE_PMD_NR
 _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)
 ^
   include/linux/compiler.h:474:4: note: in definition of macro 
'__compiletime_assert'
   prefix ## suffix();\ 
  
   ^   
   include/linux/compiler.h:491:2: note: in expansion of macro 
'_compiletime_assert'
 _compiletime_assert(condition, msg, __compiletime_assert_, __LINE__)   

 ^   
   include/linux/bug.h:51:37: note: in expansion of macro 'compiletime_assert'
#define BUILD_BUG_ON_MSG(cond, msg) compiletime_assert(!(cond), msg)  
^
   include/linux/bug.h:75:2: note: in expansion of macro 'BUILD_BUG_ON_MSG'
 BUILD_BUG_ON_MSG(condition, "BUILD_BUG_ON failed: " #condition)   
 ^  
   fs/ext4/readpage.c:144:4: note: in expansion of macro 'BUILD_BUG_ON'
   BUILD_BUG_ON(BIO_MAX_PAGES < HPAGE_PMD_NR); 
   ^  

The fixup:

diff --git a/fs/ext4/readpage.c b/fs/ext4/readpage.c
index 6d7cbddceeb2..75b2a7700c9a 100644
--- a/fs/ext4/readpage.c
+++ b/fs/ext4/readpage.c
@@ -140,7 +140,8 @@ int ext4_mpage_readpages(struct address_space *mapping,
 
block_in_file = (sector_t)page->index << (PAGE_SHIFT - blkbits);
 
-   if (PageTransHuge(page)) {
+   if (PageTransHuge(page) &&
+   IS_ENABLED(TRANSPARENT_HUGE_PAGECACHE)) {
BUILD_BUG_ON(BIO_MAX_PAGES < HPAGE_PMD_NR);
nr = HPAGE_PMD_NR * blocks_per_page;
/* XXX: need a better solution ? */
-- 
 Kirill A. Shutemov
--
To unsubscribe from this list: send the line "unsubscribe linux-block" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCHv3 19/41] block: define BIO_MAX_PAGES to HPAGE_PMD_NR if huge page cache enabled

2016-09-16 Thread Kirill A. Shutemov
On Thu, Sep 15, 2016 at 02:55:01PM +0300, Kirill A. Shutemov wrote:
> We are going to do IO a huge page a time. So we need BIO_MAX_PAGES to be
> at least HPAGE_PMD_NR. For x86-64, it's 512 pages.

0-DAY reported this:

[2.555776] PCI: Using configuration type 1 for base access
[2.870504] HugeTLB registered 2 MB page size, pre-allocated 0 pages
[2.885252] [ cut here ]
[2.887501] WARNING: CPU: 0 PID: 1 at mm/slab_common.c:98 
kmem_cache_create+0xbc/0x18b
[2.891987] Modules linked in:
[2.893538] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 
4.8.0-rc6-00021-gd96a38d #421
[2.897164]   00200246 cef0decc c141aa9e  c11279b6 cef0dee4 
c104990a
[2.908396]  0062 c1a820f0 c1b752f4 c1999b09 cef0def8 c104999c 0009 

[2.912555]   cef0df1c c11279b6  c1999afe 1800 6bc01ac0 
c1b3d0bc
[2.916733] Call Trace:
[2.930981]  [] dump_stack+0x74/0xa7
[2.933128]  [] ? kmem_cache_create+0xbc/0x18b
[2.935630]  [] __warn+0xbc/0xd3
[2.937586]  [] ? x509_key_init+0xf/0xf
[2.939837]  [] warn_slowpath_null+0x16/0x1b
[2.942279]  [] kmem_cache_create+0xbc/0x18b
[2.957745]  [] ? x509_key_init+0xf/0xf
[2.960010]  [] init_bio+0x58/0x94
[2.962048]  [] do_one_initcall+0x83/0x103
[2.964428]  [] ? parse_args+0x1c9/0x29c
[2.966725]  [] ? kernel_init_freeable+0x16f/0x20c
[2.969400]  [] kernel_init_freeable+0x18f/0x20c
[2.994076]  [] kernel_init+0xd/0xd5
[2.996185]  [] ret_from_kernel_thread+0xe/0x30
[2.998748]  [] ? rest_init+0xa6/0xa6
[3.000968] ---[ end trace 197bc755366f9a86 ]---
[3.021244] ACPI: Added _OSI(Module Device)

Fix up:

diff --git a/block/bio.c b/block/bio.c
index aa7354088008..a06bf174cddf 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -44,7 +44,8 @@
  */
 #define BV(x) { .nr_vecs = x, .name = "biovec-"__stringify(x) }
 static struct biovec_slab bvec_slabs[BVEC_POOL_NR] __read_mostly = {
-   BV(1), BV(4), BV(16), BV(64), BV(128), BV(BIO_MAX_PAGES),
+   BV(1), BV(4), BV(16), BV(64), BV(128),
+   { .nr_vecs = BIO_MAX_PAGES, .name ="biovec-max_pages" },
 };
 #undef BV
 
-- 
 Kirill A. Shutemov
--
To unsubscribe from this list: send the line "unsubscribe linux-block" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCHv3 07/41] mm, shmem: swich huge tmpfs to multi-order radix-tree entries

2016-09-16 Thread Kirill A. Shutemov
On Thu, Sep 15, 2016 at 02:54:49PM +0300, Kirill A. Shutemov wrote:
> We would need to use multi-order radix-tree entires for ext4 and other
> filesystems to have coherent view on tags (dirty/towrite) in the tree.
> 
> This patch converts huge tmpfs implementation to multi-order entries, so
> we will be able to use the same code patch for all filesystems.
> 
> Signed-off-by: Kirill A. Shutemov 

0-DAY reported this:

reproduce: make htmldocs

All warnings (new ones prefixed by >>):

   lib/crc32.c:148: warning: No description found for parameter 'tab)[256]'
   lib/crc32.c:148: warning: Excess function parameter 'tab' description in 
'crc32_le_generic'
   lib/crc32.c:293: warning: No description found for parameter 'tab)[256]'
   lib/crc32.c:293: warning: Excess function parameter 'tab' description in 
'crc32_be_generic'
   lib/crc32.c:1: warning: no structured comments found
>> mm/filemap.c:1434: warning: No description found for parameter 'start'
>> mm/filemap.c:1434: warning: Excess function parameter 'index' description in 
>> 'find_get_pages_contig'
>> mm/filemap.c:1525: warning: No description found for parameter 'indexp'
>> mm/filemap.c:1525: warning: Excess function parameter 'index' description in 
>> 'find_get_pages_tag'

The fixup:

diff --git a/mm/filemap.c b/mm/filemap.c
index c69b1204744a..1ef20dd45b6b 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1548,7 +1548,7 @@ repeat:
 /**
  * find_get_pages_contig - gang contiguous pagecache lookup
  * @mapping:   The address_space to search
- * @index: The starting page index
+ * @start: The starting page index
  * @nr_pages:  The maximum number of pages
  * @pages: Where the resulting pages are placed
  *
@@ -1641,7 +1641,7 @@ EXPORT_SYMBOL(find_get_pages_contig);
 /**
  * find_get_pages_tag - find and return pages that match @tag
  * @mapping:   the address_space to search
- * @index: the starting page index
+ * @indexp:the starting page index
  * @tag:   the tag index
  * @nr_pages:  the maximum number of pages
  * @pages: where the resulting pages are placed
-- 
 Kirill A. Shutemov
--
To unsubscribe from this list: send the line "unsubscribe linux-block" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] lightnvm: propagate device_add() error code

2016-09-16 Thread Matias Bjørling

On 09/15/2016 05:53 PM, Arnd Bergmann wrote:

device_add() may fail, and all callers are supposed to check the
return value, but one new user in lightnvm doesn't:

drivers/lightnvm/sysfs.c: In function 'nvm_sysfs_register_dev':
drivers/lightnvm/sysfs.c:184:2: error: ignoring return value of 'device_add', 
declared with attribute warn_unused_result [-Werror=unused-result]

This changes the caller to propagate any error codes, which avoids
the warning.

Signed-off-by: Arnd Bergmann 
Fixes: 38c9e260b9f9 ("lightnvm: expose device geometry through sysfs")
---
  drivers/lightnvm/lightnvm.h | 2 +-
  drivers/lightnvm/sysfs.c| 9 ++---
  2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/drivers/lightnvm/lightnvm.h b/drivers/lightnvm/lightnvm.h
index 93f1aacc9f02..305c181509a6 100644
--- a/drivers/lightnvm/lightnvm.h
+++ b/drivers/lightnvm/lightnvm.h
@@ -24,7 +24,7 @@
  #include 

  /* core -> sysfs.c */
-int nvm_sysfs_register_dev(struct nvm_dev *);
+int __must_check nvm_sysfs_register_dev(struct nvm_dev *);
  void nvm_sysfs_unregister_dev(struct nvm_dev *);
  int nvm_sysfs_register(void);
  void nvm_sysfs_unregister(void);
diff --git a/drivers/lightnvm/sysfs.c b/drivers/lightnvm/sysfs.c
index 72ad089c0269..0338c27ab95a 100644
--- a/drivers/lightnvm/sysfs.c
+++ b/drivers/lightnvm/sysfs.c
@@ -174,6 +174,8 @@ static struct device_type nvm_type = {

  int nvm_sysfs_register_dev(struct nvm_dev *dev)
  {
+   int ret;
+
if (!dev->parent_dev)
return 0;

@@ -181,11 +183,12 @@ int nvm_sysfs_register_dev(struct nvm_dev *dev)
dev_set_name(&dev->dev, "%s", dev->name);
dev->dev.type = &nvm_type;
device_initialize(&dev->dev);
-   device_add(&dev->dev);
+   ret = device_add(&dev->dev);

-   blk_mq_register_dev(&dev->dev, dev->q);
+   if (!ret)
+   blk_mq_register_dev(&dev->dev, dev->q);

-   return 0;
+   return ret;
  }

  void nvm_sysfs_unregister_dev(struct nvm_dev *dev)



Thans Arnd. Applied for 4.9.
--
To unsubscribe from this list: send the line "unsubscribe linux-block" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 6/6] media/cobalt: use pci_irq_allocate_vectors

2016-09-16 Thread Christoph Hellwig
On Fri, Sep 16, 2016 at 10:01:42AM +0200, Hans Verkuil wrote:
> PCI_IRQ_MSI is unknown, I assume that this will appear in 4.9?

The flag is in 4.8-rc.
--
To unsubscribe from this list: send the line "unsubscribe linux-block" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH 6/6] media/cobalt: use pci_irq_allocate_vectors

2016-09-16 Thread Hans Verkuil
Hi Christoph,

On 09/11/2016 03:31 PM, Christoph Hellwig wrote:
> Simply the interrupt setup by using the new PCI layer helpers.
> 
> Despite using pci_enable_msi_range, this driver was only requesting a
> single MSI vector anyway.
> 
> Signed-off-by: Christoph Hellwig 
> ---
>  drivers/media/pci/cobalt/cobalt-driver.c | 8 ++--
>  drivers/media/pci/cobalt/cobalt-driver.h | 2 --
>  2 files changed, 2 insertions(+), 8 deletions(-)
> 
> diff --git a/drivers/media/pci/cobalt/cobalt-driver.c 
> b/drivers/media/pci/cobalt/cobalt-driver.c
> index 476f7f0..5a0a9e4 100644
> --- a/drivers/media/pci/cobalt/cobalt-driver.c
> +++ b/drivers/media/pci/cobalt/cobalt-driver.c
> @@ -307,9 +307,7 @@ static void cobalt_pci_iounmap(struct cobalt *cobalt, 
> struct pci_dev *pci_dev)
>  static void cobalt_free_msi(struct cobalt *cobalt, struct pci_dev *pci_dev)
>  {
>   free_irq(pci_dev->irq, (void *)cobalt);
> -
> - if (cobalt->msi_enabled)
> - pci_disable_msi(pci_dev);
> + pci_free_irq_vectors(pci_dev);
>  }
>  
>  static int cobalt_setup_pci(struct cobalt *cobalt, struct pci_dev *pci_dev,
> @@ -386,14 +384,12 @@ static int cobalt_setup_pci(struct cobalt *cobalt, 
> struct pci_dev *pci_dev,
>  from being generated. */
>   cobalt_set_interrupt(cobalt, false);
>  
> - if (pci_enable_msi_range(pci_dev, 1, 1) < 1) {
> + if (pci_alloc_irq_vectors(pci_dev, 1, 1, PCI_IRQ_MSI) < 1) {

PCI_IRQ_MSI is unknown, I assume that this will appear in 4.9?

Looks good otherwise.

Regards,

Hans

>   cobalt_err("Could not enable MSI\n");
> - cobalt->msi_enabled = false;
>   ret = -EIO;
>   goto err_release;
>   }
>   msi_config_show(cobalt, pci_dev);
> - cobalt->msi_enabled = true;
>  
>   /* Register IRQ */
>   if (request_irq(pci_dev->irq, cobalt_irq_handler, IRQF_SHARED,
> diff --git a/drivers/media/pci/cobalt/cobalt-driver.h 
> b/drivers/media/pci/cobalt/cobalt-driver.h
> index ed00dc9..00f773e 100644
> --- a/drivers/media/pci/cobalt/cobalt-driver.h
> +++ b/drivers/media/pci/cobalt/cobalt-driver.h
> @@ -287,8 +287,6 @@ struct cobalt {
>   u32 irq_none;
>   u32 irq_full_fifo;
>  
> - bool msi_enabled;
> -
>   /* omnitek dma */
>   int dma_channels;
>   int first_fifo_channel;
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-block" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html