From: Hannes Reinecke <hare@suse.de>
To: Jens Axboe <axboe@fb.com>
Cc: linux-block@vger.kernel.org, linux-scsi@vger.kernel.org,
Damien Le Moal <damien.lemoal@hgst.com>,
Hannes Reinecke <hare@suse.de>
Subject: [PATCH 3/6] block: Implement support for zoned block devices
Date: Tue, 19 Jul 2016 15:20:36 +0200 [thread overview]
Message-ID: <1468934439-93579-4-git-send-email-hare@suse.de> (raw)
In-Reply-To: <1468934439-93579-1-git-send-email-hare@suse.de>
Implement a RB-Tree holding the zone information and
add support functions for maintaining the RB-Tree.
Signed-off-by: Hannes Reinecke <hare@suse.de>
---
block/Kconfig | 9 +++++++
block/Makefile | 1 +
block/blk-core.c | 5 ++++
block/blk-zoned.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++
include/linux/blkdev.h | 47 +++++++++++++++++++++++++++++++++
5 files changed, 132 insertions(+)
create mode 100644 block/blk-zoned.c
diff --git a/block/Kconfig b/block/Kconfig
index 0363cd7..8162312 100644
--- a/block/Kconfig
+++ b/block/Kconfig
@@ -113,6 +113,15 @@ config BLK_DEV_THROTTLING
See Documentation/cgroups/blkio-controller.txt for more information.
+config BLK_DEV_ZONED
+ bool "Zoned block device support"
+ default n
+ ---help---
+ Block layer zoned block device support. This option enables
+ support for zoned block (ZAC/ZBC) devices.
+
+ Say yes here if you have a ZAC or ZBC storage device.
+
config BLK_CMDLINE_PARSER
bool "Block device command line partition parser"
default n
diff --git a/block/Makefile b/block/Makefile
index 9eda232..bc9e62c 100644
--- a/block/Makefile
+++ b/block/Makefile
@@ -15,6 +15,7 @@ obj-$(CONFIG_BLK_DEV_BSG) += bsg.o
obj-$(CONFIG_BLK_DEV_BSGLIB) += bsg-lib.o
obj-$(CONFIG_BLK_CGROUP) += blk-cgroup.o
obj-$(CONFIG_BLK_DEV_THROTTLING) += blk-throttle.o
+obj-$(CONFIG_BLK_DEV_ZONED) += blk-zoned.o
obj-$(CONFIG_IOSCHED_NOOP) += noop-iosched.o
obj-$(CONFIG_IOSCHED_DEADLINE) += deadline-iosched.o
obj-$(CONFIG_IOSCHED_CFQ) += cfq-iosched.o
diff --git a/block/blk-core.c b/block/blk-core.c
index 2475b1c7..e273194 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -588,6 +588,8 @@ void blk_cleanup_queue(struct request_queue *q)
blk_mq_free_queue(q);
percpu_ref_exit(&q->q_usage_counter);
+ blk_drop_zones(q);
+
spin_lock_irq(lock);
if (q->queue_lock != &q->__queue_lock)
q->queue_lock = &q->__queue_lock;
@@ -724,6 +726,9 @@ struct request_queue *blk_alloc_queue_node(gfp_t gfp_mask, int node_id)
#ifdef CONFIG_BLK_CGROUP
INIT_LIST_HEAD(&q->blkg_list);
#endif
+#ifdef CONFIG_BLK_DEV_ZONED
+ q->zones = RB_ROOT;
+#endif
INIT_DELAYED_WORK(&q->delay_work, blk_delay_work);
kobject_init(&q->kobj, &blk_queue_ktype);
diff --git a/block/blk-zoned.c b/block/blk-zoned.c
new file mode 100644
index 0000000..975e863
--- /dev/null
+++ b/block/blk-zoned.c
@@ -0,0 +1,70 @@
+/*
+ * Zoned block device handling
+ *
+ * Copyright (c) 2015, Hannes Reinecke
+ * Copyright (c) 2015, SUSE Linux GmbH
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/blkdev.h>
+#include <linux/rbtree.h>
+
+struct blk_zone *blk_lookup_zone(struct request_queue *q, sector_t lba)
+{
+ struct rb_root *root = &q->zones;
+ struct rb_node *node = root->rb_node;
+
+ while (node) {
+ struct blk_zone *zone = container_of(node, struct blk_zone,
+ node);
+
+ if (lba < zone->start)
+ node = node->rb_left;
+ else if (lba >= zone->start + zone->len)
+ node = node->rb_right;
+ else
+ return zone;
+ }
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(blk_lookup_zone);
+
+struct blk_zone *blk_insert_zone(struct request_queue *q, struct blk_zone *data)
+{
+ struct rb_root *root = &q->zones;
+ struct rb_node **new = &(root->rb_node), *parent = NULL;
+
+ /* Figure out where to put new node */
+ while (*new) {
+ struct blk_zone *this = container_of(*new, struct blk_zone,
+ node);
+ parent = *new;
+ if (data->start + data->len <= this->start)
+ new = &((*new)->rb_left);
+ else if (data->start >= this->start + this->len)
+ new = &((*new)->rb_right);
+ else {
+ /* Return existing zone */
+ return this;
+ }
+ }
+ /* Add new node and rebalance tree. */
+ rb_link_node(&data->node, parent, new);
+ rb_insert_color(&data->node, root);
+
+ return NULL;
+}
+EXPORT_SYMBOL_GPL(blk_insert_zone);
+
+void blk_drop_zones(struct request_queue *q)
+{
+ struct rb_root *root = &q->zones;
+ struct blk_zone *zone, *next;
+
+ rbtree_postorder_for_each_entry_safe(zone, next, root, node) {
+ kfree(zone);
+ }
+ q->zones = RB_ROOT;
+}
+EXPORT_SYMBOL_GPL(blk_drop_zones);
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 3d9cf32..d5e3d8b 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -249,6 +249,50 @@ struct blk_queue_tag {
#define BLK_SCSI_MAX_CMDS (256)
#define BLK_SCSI_CMD_PER_LONG (BLK_SCSI_MAX_CMDS / (sizeof(long) * 8))
+#ifdef CONFIG_BLK_DEV_ZONED
+enum blk_zone_type {
+ BLK_ZONE_TYPE_UNKNOWN,
+ BLK_ZONE_TYPE_CONVENTIONAL,
+ BLK_ZONE_TYPE_SEQWRITE_REQ,
+ BLK_ZONE_TYPE_SEQWRITE_PREF,
+ BLK_ZONE_TYPE_RESERVED,
+};
+
+enum blk_zone_state {
+ BLK_ZONE_UNKNOWN,
+ BLK_ZONE_NO_WP,
+ BLK_ZONE_OPEN,
+ BLK_ZONE_READONLY,
+ BLK_ZONE_OFFLINE,
+ BLK_ZONE_BUSY,
+};
+
+struct blk_zone {
+ struct rb_node node;
+ spinlock_t lock;
+ sector_t start;
+ size_t len;
+ sector_t wp;
+ enum blk_zone_type type;
+ enum blk_zone_state state;
+ void *private_data;
+};
+
+#define blk_zone_is_smr(z) ((z)->type == BLK_ZONE_TYPE_SEQWRITE_REQ || \
+ (z)->type == BLK_ZONE_TYPE_SEQWRITE_PREF)
+
+#define blk_zone_is_cmr(z) ((z)->type == BLK_ZONE_TYPE_CONVENTIONAL)
+#define blk_zone_is_full(z) ((z)->wp == (z)->start + (z)->len)
+#define blk_zone_is_empty(z) ((z)->wp == (z)->start)
+
+extern struct blk_zone *blk_lookup_zone(struct request_queue *, sector_t);
+extern struct blk_zone *blk_insert_zone(struct request_queue *,
+ struct blk_zone *);
+extern void blk_drop_zones(struct request_queue *);
+#else
+static inline void blk_drop_zones(struct request_queue *q) { };
+#endif
+
struct queue_limits {
unsigned long bounce_pfn;
unsigned long seg_boundary_mask;
@@ -421,6 +465,9 @@ struct request_queue {
struct queue_limits limits;
+#ifdef CONFIG_BLK_DEV_ZONED
+ struct rb_root zones;
+#endif
/*
* sg stuff
*/
--
1.8.5.6
next prev parent reply other threads:[~2016-07-19 13:20 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-07-19 13:20 [PATCH 0/6] Support for zoned block devices Hannes Reinecke
2016-07-19 13:20 ` [PATCH 1/6] blk-sysfs: Add 'chunk_sectors' to sysfs attributes Hannes Reinecke
2016-07-20 1:02 ` Damien Le Moal
2016-07-21 5:59 ` Christoph Hellwig
2016-07-22 20:35 ` Martin K. Petersen
2016-07-19 13:20 ` [PATCH 2/6] block: update chunk_sectors in blk_stack_limits() Hannes Reinecke
2016-07-20 1:05 ` Damien Le Moal
2016-07-21 5:59 ` Christoph Hellwig
2016-07-22 20:46 ` Martin K. Petersen
2016-07-19 13:20 ` Hannes Reinecke [this message]
2016-07-20 1:05 ` [PATCH 3/6] block: Implement support for zoned block devices Damien Le Moal
2016-07-19 13:20 ` [PATCH 4/6] block: Add 'zoned' sysfs queue attribute Hannes Reinecke
2016-07-20 1:07 ` Damien Le Moal
2016-07-22 20:45 ` Martin K. Petersen
2016-07-23 12:43 ` Hannes Reinecke
2016-07-23 22:13 ` Bart Van Assche
2016-07-24 7:10 ` Hannes Reinecke
2016-07-24 13:37 ` Bart Van Assche
2016-07-24 13:51 ` Bart Van Assche
2016-07-24 23:22 ` Damien Le Moal
2016-07-25 5:56 ` Hannes Reinecke
2016-07-25 14:45 ` Jens Axboe
2016-07-24 23:16 ` Damien Le Moal
2016-07-25 14:44 ` Jens Axboe
2016-07-19 13:20 ` [PATCH 5/6] block: Introduce BLKPREP_DONE Hannes Reinecke
2016-07-20 1:10 ` Damien Le Moal
2016-07-21 5:58 ` Christoph Hellwig
2016-07-21 6:01 ` Hannes Reinecke
2016-07-19 13:20 ` [PATCH 6/6] block: Add 'BLK_MQ_RQ_QUEUE_DONE' return value Hannes Reinecke
2016-07-20 1:11 ` Damien Le Moal
2016-07-21 5:53 ` Christoph Hellwig
2016-07-21 6:00 ` Hannes Reinecke
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1468934439-93579-4-git-send-email-hare@suse.de \
--to=hare@suse.de \
--cc=axboe@fb.com \
--cc=damien.lemoal@hgst.com \
--cc=linux-block@vger.kernel.org \
--cc=linux-scsi@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).