[PATCH rfc 10/10] target: Use non-selective polling
Nicholas A. Bellinger
nab at linux-iscsi.org
Sat Mar 18 16:58:01 PDT 2017
Hey Sagi,
On Thu, 2017-03-09 at 15:16 +0200, Sagi Grimberg wrote:
> It doesn't really make sense to do selective polling
> because we never care about specific IOs. Non selective
> polling can actually help by doing some useful work
> while we're submitting a command.
>
> We ask for a batch of (magic) 4 completions which looks
> like a decent network<->backend proportion, if less are
> available we'll see less.
>
> Signed-off-by: Sagi Grimberg <sagi at grimberg.me>
> ---
> drivers/target/target_core_iblock.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c
> index d316ed537d59..00726b6e51c4 100644
> --- a/drivers/target/target_core_iblock.c
> +++ b/drivers/target/target_core_iblock.c
> @@ -757,6 +757,7 @@ iblock_execute_rw(struct se_cmd *cmd, struct scatterlist *sgl, u32 sgl_nents,
> }
>
> iblock_submit_bios(&list);
> + blk_mq_poll_batch(bdev_get_queue(IBLOCK_DEV(dev)->ibd_bd), 4);
> iblock_complete_cmd(cmd);
> return 0;
>
Let's make 'batch' into a backend specific attribute so it can be
changed on-the-fly per device, instead of a hard-coded value.
Here's a quick patch to that end. Feel free to fold it into your
series.
Beyond that:
Acked-by: Nicholas Bellinger <nab at linux-iscsi.org>
>From c2c2a6185fc92132f61beb1708adbef9ea3995e9 Mon Sep 17 00:00:00 2001
From: Nicholas Bellinger <nab at linux-iscsi.org>
Date: Sat, 18 Mar 2017 20:29:05 +0000
Subject: [PATCH] target/iblock: Add poll_batch attribute
Signed-off-by: Nicholas Bellinger <nab at linux-iscsi.org>
---
drivers/target/target_core_iblock.c | 65 ++++++++++++++++++++++++++++++++---
drivers/target/target_core_iblock.h | 2 ++
2 files changed, 63 insertions(+), 4 deletions(-)
diff --git a/drivers/target/target_core_iblock.c b/drivers/target/target_core_iblock.c
index 00726b6..9396a60 100644
--- a/drivers/target/target_core_iblock.c
+++ b/drivers/target/target_core_iblock.c
@@ -35,6 +35,7 @@
#include <linux/genhd.h>
#include <linux/file.h>
#include <linux/module.h>
+#include <linux/configfs.h>
#include <scsi/scsi_proto.h>
#include <asm/unaligned.h>
@@ -114,6 +115,7 @@ static int iblock_configure_device(struct se_device *dev)
goto out_free_bioset;
}
ib_dev->ibd_bd = bd;
+ ib_dev->poll_batch = IBLOCK_POLL_BATCH;
q = bdev_get_queue(bd);
@@ -757,7 +759,8 @@ static ssize_t iblock_show_configfs_dev_params(struct se_device *dev, char *b)
}
iblock_submit_bios(&list);
- blk_mq_poll_batch(bdev_get_queue(IBLOCK_DEV(dev)->ibd_bd), 4);
+ blk_mq_poll_batch(bdev_get_queue(IBLOCK_DEV(dev)->ibd_bd),
+ IBLOCK_DEV(dev)->poll_batch);
iblock_complete_cmd(cmd);
return 0;
@@ -840,7 +843,38 @@ static bool iblock_get_write_cache(struct se_device *dev)
return test_bit(QUEUE_FLAG_WC, &q->queue_flags);
}
-static const struct target_backend_ops iblock_ops = {
+static ssize_t iblock_poll_batch_show(struct config_item *item, char *page)
+{
+ struct se_dev_attrib *da = container_of(to_config_group(item),
+ struct se_dev_attrib, da_group);
+ struct iblock_dev *ibd = container_of(da->da_dev,
+ struct iblock_dev, dev);
+
+ return snprintf(page, PAGE_SIZE, "%u\n", ibd->poll_batch);
+}
+
+static ssize_t iblock_poll_batch_store(struct config_item *item, const char *page,
+ size_t count)
+{
+ struct se_dev_attrib *da = container_of(to_config_group(item),
+ struct se_dev_attrib, da_group);
+ struct iblock_dev *ibd = container_of(da->da_dev,
+ struct iblock_dev, dev);
+ u32 val;
+ int ret;
+
+ ret = kstrtou32(page, 0, &val);
+ if (ret < 0)
+ return ret;
+
+ ibd->poll_batch = val;
+ return count;
+}
+CONFIGFS_ATTR(iblock_, poll_batch);
+
+static struct configfs_attribute **iblock_attrs;
+
+static struct target_backend_ops iblock_ops = {
.name = "iblock",
.inquiry_prod = "IBLOCK",
.inquiry_rev = IBLOCK_VERSION,
@@ -860,17 +894,40 @@ static bool iblock_get_write_cache(struct se_device *dev)
.get_io_min = iblock_get_io_min,
.get_io_opt = iblock_get_io_opt,
.get_write_cache = iblock_get_write_cache,
- .tb_dev_attrib_attrs = sbc_attrib_attrs,
+ .tb_dev_attrib_attrs = NULL,
};
static int __init iblock_module_init(void)
{
- return transport_backend_register(&iblock_ops);
+ int rc, i, len = 0;
+
+ for (i = 0; sbc_attrib_attrs[i] != NULL; i++) {
+ len += sizeof(struct configfs_attribute *);
+ }
+ len += sizeof(struct configfs_attribute *) * 2;
+
+ iblock_attrs = kzalloc(len, GFP_KERNEL);
+ if (!iblock_attrs)
+ return -ENOMEM;
+
+ for (i = 0; sbc_attrib_attrs[i] != NULL; i++) {
+ iblock_attrs[i] = sbc_attrib_attrs[i];
+ }
+ iblock_attrs[i] = &iblock_attr_poll_batch;
+ iblock_ops.tb_dev_attrib_attrs = iblock_attrs;
+
+ rc = transport_backend_register(&iblock_ops);
+ if (rc) {
+ kfree(iblock_attrs);
+ return rc;
+ }
+ return 0;
}
static void __exit iblock_module_exit(void)
{
target_backend_unregister(&iblock_ops);
+ kfree(iblock_attrs);
}
MODULE_DESCRIPTION("TCM IBLOCK subsystem plugin");
diff --git a/drivers/target/target_core_iblock.h b/drivers/target/target_core_iblock.h
index 718d3fc..308b5c2 100644
--- a/drivers/target/target_core_iblock.h
+++ b/drivers/target/target_core_iblock.h
@@ -8,6 +8,7 @@
#define IBLOCK_MAX_CDBS 16
#define IBLOCK_LBA_SHIFT 9
+#define IBLOCK_POLL_BATCH 4
struct iblock_req {
atomic_t pending;
@@ -23,6 +24,7 @@ struct iblock_dev {
struct bio_set *ibd_bio_set;
struct block_device *ibd_bd;
bool ibd_readonly;
+ unsigned int poll_batch;
} ____cacheline_aligned;
#endif /* TARGET_CORE_IBLOCK_H */
--
1.7.10.4
More information about the Linux-nvme
mailing list