Re: [PATCH RFC v6 04/10] blk-mq: Facilitate a shared sbitmap per tagset

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Hannes,

+
+void blk_mq_exit_shared_sbitmap(struct blk_mq_tag_set *tag_set)
+{
+    sbitmap_queue_free(&tag_set->__bitmap_tags);
+    sbitmap_queue_free(&tag_set->__breserved_tags);
+}
+
+struct blk_mq_tags *blk_mq_init_tags(struct blk_mq_tag_set *set,
+                     unsigned int total_tags,
                       unsigned int reserved_tags,
                       int node, int alloc_policy)
  {
@@ -480,6 +506,7 @@ struct blk_mq_tags *blk_mq_init_tags(unsigned int total_tags,
  void blk_mq_free_tags(struct blk_mq_tags *tags)
  {
+    /* Do not use tags->{bitmap, breserved}_tags */
      sbitmap_queue_free(&tags->__bitmap_tags);
      sbitmap_queue_free(&tags->__breserved_tags);
      kfree(tags);
Hmm. This is essentially the same as blk_mq_exit_shared_sbitmap().

It does the same thing, but takes different argument types: struct blk_mq_tag_set * vs struct blk_mq_tags *

Please call into that function or clarify the relationship between both.
And modify the comment; it's not about the 'use' but rather the freeing

ok

of the structures, and ->bitmap/breserved just point to the __ variants.

Please note that I had to change blk_mq_init_tags() from v5 to now continue to init the blk_mq_tags.__{bitmap, breserved}_tags always. The reason is that the following would now be broken for scheduler tags when BLK_MQ_F_TAG_HCTX_SHARED is set, ***:

struct blk_mq_tags *blk_mq_init_tags(struct blk_mq_tag_set *set, ...)
{
	struct blk_mq_tags *tags;
	...

	tags->nr_tags = total_tags;
	tags->nr_reserved_tags = reserved_tags;

	if (blk_mq_is_sbitmap_shared(set)) ***
		return tags;

	if (blk_mq_init_bitmap_tags(tags, node, alloc_policy) < 0) {
		...
	}
	return tags;
}

Keeping the blk_mq_is_sbitmap_shared() check would mean that we never call blk_mq_init_bitmap_tags() for scheduler tags for when BLK_MQ_F_TAG_HCTX_SHARED is set.

As such, I removed the blk_mq_is_sbitmap_shared() check, and we still init the blk_mq_tags bitmaps always. Hence we still need to free them.

And as I noted in the hctx_tags_bitmap_show() change (patch #5), we could actually reuse blk_mq_tags.__bitmap_tags.sb in that function instead of using a local temp sbitmap.


@@ -538,6 +565,11 @@ int blk_mq_tag_update_depth(struct blk_mq_hw_ctx *hctx,
      return 0;
  }
+void blk_mq_tag_resize_shared_sbitmap(struct blk_mq_tag_set *set, unsigned int size)
+{
+    sbitmap_queue_resize(&set->__bitmap_tags, size - set->reserved_tags);
+}
+

[...]

      return 0;
+out_free_mq_rq_maps:
+    for (i = 0; i < set->nr_hw_queues; i++)
+        blk_mq_free_rq_map(set->tags[i]);
  out_free_mq_map:
      for (i = 0; i < set->nr_maps; i++) {
          kfree(set->map[i].mq_map);
@@ -3170,6 +3189,9 @@ void blk_mq_free_tag_set(struct blk_mq_tag_set *set)
      for (i = 0; i < set->nr_hw_queues; i++)
          blk_mq_free_map_and_requests(set, i);
+    if (blk_mq_is_sbitmap_shared(set))
+        blk_mq_exit_shared_sbitmap(set);
+
      for (j = 0; j < set->nr_maps; j++) {
          kfree(set->map[j].mq_map);
          set->map[j].mq_map = NULL;
@@ -3206,6 +3228,8 @@ int blk_mq_update_nr_requests(struct request_queue *q, unsigned int nr)
          if (!hctx->sched_tags) {
              ret = blk_mq_tag_update_depth(hctx, &hctx->tags, nr,
                              false);
+            if (!ret && blk_mq_is_sbitmap_shared(set))
+                blk_mq_tag_resize_shared_sbitmap(set, nr);
          } else {
              ret = blk_mq_tag_update_depth(hctx, &hctx->sched_tags,
                              nr, true);
diff --git a/block/blk-mq.h b/block/blk-mq.h
index 10bfdfb494fa..dde2d29f0ce5 100644
--- a/block/blk-mq.h
+++ b/block/blk-mq.h
@@ -158,6 +158,11 @@ struct blk_mq_alloc_data {
      struct blk_mq_hw_ctx *hctx;
  };
+static inline bool blk_mq_is_sbitmap_shared(struct blk_mq_tag_set *tag_set)
+{
+    return tag_set->flags & BLK_MQ_F_TAG_HCTX_SHARED;
+}
+
When is that set?

It set later for SCSI hosts in scsi_mq_setup_tags(), for when .host_tagset is set.

And to my understanding it contingent on the ->bitmap pointer _not_ pointing to ->__bitmap.
Can we use this as a test and drop this flag?

Maybe, but we need some flag passed to blk_mq_alloc_set() to request to use the shared sbitmap.

Thanks,
John



[Index of Archives]     [Linux RAID]     [Linux SCSI]     [Linux ATA RAID]     [IDE]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Device Mapper]

  Powered by Linux