Skip to content

Commit 6248640

Browse files
committed
Add blk_mq shared tags support for dev -d/-D
When blk_mq shared tags enabled for devices like scsi, the IO status is incorrect, e.g: crash> dev -d MAJOR GENDISK NAME REQUEST_QUEUE TOTAL ASYNC SYNC 8 ffff90528df86000 sda ffff9052a3d61800 144 144 0 8 ffff905280718c00 sdb ffff9052a3d63c00 48 48 0 crash> epython rqlist ffff90528e94a5c0 sda is unknown, deadline: 89.992 (90) rq_alloc: 0.196 ffff90528e92f700 sda is unknown, deadline: 89.998 (90) rq_alloc: 0.202 ffff90528e95ccc0 sda is unknown, deadline: 89.999 (90) rq_alloc: 0.203 ffff90528e968bc0 sdb is unknown, deadline: 89.997 (90) rq_alloc: 0.201 The root cause is: for shared tags case, only the shared tags are put into count. Without this patch, tags of all the hw_ctx are counted, which is incorrect. After apply the patch: crash> dev -d MAJOR GENDISK NAME REQUEST_QUEUE TOTAL READ WRITE 8 ffff90528df86000 sda ffff9052a3d61800 3 3 0 8 ffff905280718c00 sdb ffff9052a3d63c00 1 1 0 This patch makes the following modification: 1) blk_mq shared tag support. 2) Function renaming: queue_for_each_hw_ctx -> blk_mq_queue_tag_busy_iter, because the latter is more close to the corresponding kernel function. 3) Extract a new queue_for_each_hw_ctx() function to be called for both shared-tags case and the hw_ctx case. Note: The patch is safe for earlier kernels which have no blk_mq shared tags implemented, because the blk_mq_is_shared_tags() check will exit safely. Signed-off-by: Tao Liu <ltao@redhat.com>
1 parent 2c69f93 commit 6248640

File tree

3 files changed

+76
-29
lines changed

3 files changed

+76
-29
lines changed

defs.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2271,6 +2271,9 @@ struct offset_table { /* stash of commonly-used offsets */
22712271
long task_struct_thread_context_x28;
22722272
long neigh_table_hash_heads;
22732273
long neighbour_hash;
2274+
long request_queue_tag_set;
2275+
long blk_mq_tag_set_flags;
2276+
long blk_mq_tag_set_shared_tags;
22742277
};
22752278

22762279
struct size_table { /* stash of commonly-used sizes */

dev.c

Lines changed: 67 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -4326,6 +4326,12 @@ struct bt_iter_data {
43264326
#define MQ_RQ_IN_FLIGHT 1
43274327
#define REQ_OP_BITS 8
43284328
#define REQ_OP_MASK ((1 << REQ_OP_BITS) - 1)
4329+
#define BLK_MQ_F_TAG_HCTX_SHARED (1 << 3)
4330+
4331+
static bool blk_mq_is_shared_tags(unsigned int flags)
4332+
{
4333+
return flags & BLK_MQ_F_TAG_HCTX_SHARED;
4334+
}
43294335

43304336
static uint op_is_write(uint op)
43314337
{
@@ -4403,43 +4409,72 @@ static void bt_for_each(ulong q, ulong tags, ulong sbq, uint reserved, uint nr_r
44034409
sbitmap_for_each_set(&sc, bt_iter, &iter_data);
44044410
}
44054411

4406-
static void queue_for_each_hw_ctx(ulong q, ulong *hctx, uint cnt, struct diskio *dio)
4412+
static bool queue_for_each_hw_ctx(ulong q, ulong blk_mq_tags_ptr,
4413+
bool bitmap_tags_is_ptr, struct diskio *dio)
44074414
{
4408-
uint i;
4415+
uint nr_reserved_tags = 0;
4416+
ulong tags = 0, addr = 0;
4417+
bool ret = FALSE;
4418+
4419+
if (!readmem(blk_mq_tags_ptr, KVADDR, &tags, sizeof(ulong),
4420+
"blk_mq_hw_ctx.tags", RETURN_ON_ERROR))
4421+
goto out;
4422+
4423+
addr = tags + OFFSET(blk_mq_tags_nr_reserved_tags);
4424+
if (!readmem(addr, KVADDR, &nr_reserved_tags, sizeof(uint),
4425+
"blk_mq_tags_nr_reserved_tags", RETURN_ON_ERROR))
4426+
goto out;
4427+
4428+
if (nr_reserved_tags) {
4429+
addr = tags + OFFSET(blk_mq_tags_breserved_tags);
4430+
if (bitmap_tags_is_ptr &&
4431+
!readmem(addr, KVADDR, &addr, sizeof(ulong),
4432+
"blk_mq_tags.bitmap_tags", RETURN_ON_ERROR))
4433+
goto out;
4434+
bt_for_each(q, tags, addr, 1, nr_reserved_tags, dio);
4435+
}
4436+
addr = tags + OFFSET(blk_mq_tags_bitmap_tags);
4437+
if (bitmap_tags_is_ptr &&
4438+
!readmem(addr, KVADDR, &addr, sizeof(ulong),
4439+
"blk_mq_tags.bitmap_tags", RETURN_ON_ERROR))
4440+
goto out;
4441+
bt_for_each(q, tags, addr, 0, nr_reserved_tags, dio);
4442+
4443+
ret = TRUE;
4444+
out:
4445+
return ret;
4446+
}
4447+
4448+
/*
4449+
* Replica of kernel block/blk-mq-tag.c:blk_mq_queue_tag_busy_iter()
4450+
*/
4451+
static void blk_mq_queue_tag_busy_iter(ulong q, ulong *hctx, uint cnt,
4452+
struct diskio *dio)
4453+
{
4454+
uint i, flags;
44094455
int bitmap_tags_is_ptr = 0;
4456+
ulong addr = 0;
44104457

44114458
if (MEMBER_TYPE("blk_mq_tags", "bitmap_tags") == TYPE_CODE_PTR)
44124459
bitmap_tags_is_ptr = 1;
44134460

4414-
for (i = 0; i < cnt; i++) {
4415-
ulong addr = 0, tags = 0;
4416-
uint nr_reserved_tags = 0;
4461+
readmem(q + OFFSET(request_queue_tag_set), KVADDR, &addr,
4462+
sizeof(ulong), "request_queue.tag_set", RETURN_ON_ERROR);
44174463

4418-
/* Tags owned by the block driver */
4419-
addr = hctx[i] + OFFSET(blk_mq_hw_ctx_tags);
4420-
if (!readmem(addr, KVADDR, &tags, sizeof(ulong),
4421-
"blk_mq_hw_ctx.tags", RETURN_ON_ERROR))
4422-
break;
4464+
readmem(addr + OFFSET(blk_mq_tag_set_flags), KVADDR,
4465+
&flags, sizeof(uint), "blk_mq_tag_set.flags", RETURN_ON_ERROR);
44234466

4424-
addr = tags + OFFSET(blk_mq_tags_nr_reserved_tags);
4425-
if (!readmem(addr, KVADDR, &nr_reserved_tags, sizeof(uint),
4426-
"blk_mq_tags_nr_reserved_tags", RETURN_ON_ERROR))
4427-
break;
4467+
if (blk_mq_is_shared_tags(flags)) {
4468+
addr = addr + OFFSET(blk_mq_tag_set_shared_tags);
4469+
queue_for_each_hw_ctx(q, addr, bitmap_tags_is_ptr, dio);
4470+
return;
4471+
}
44284472

4429-
if (nr_reserved_tags) {
4430-
addr = tags + OFFSET(blk_mq_tags_breserved_tags);
4431-
if (bitmap_tags_is_ptr &&
4432-
!readmem(addr, KVADDR, &addr, sizeof(ulong),
4433-
"blk_mq_tags.bitmap_tags", RETURN_ON_ERROR))
4434-
break;
4435-
bt_for_each(q, tags, addr, 1, nr_reserved_tags, dio);
4436-
}
4437-
addr = tags + OFFSET(blk_mq_tags_bitmap_tags);
4438-
if (bitmap_tags_is_ptr &&
4439-
!readmem(addr, KVADDR, &addr, sizeof(ulong),
4440-
"blk_mq_tags.bitmap_tags", RETURN_ON_ERROR))
4441-
break;
4442-
bt_for_each(q, tags, addr, 0, nr_reserved_tags, dio);
4473+
for (i = 0; i < cnt; i++) {
4474+
/* Tags owned by the block driver */
4475+
addr = hctx[i] + OFFSET(blk_mq_hw_ctx_tags);
4476+
if (queue_for_each_hw_ctx(q, addr, bitmap_tags_is_ptr, dio) == FALSE)
4477+
return;
44434478
}
44444479
}
44454480

@@ -4489,7 +4524,7 @@ static void get_mq_diskio_from_hw_queues(ulong q, struct diskio *dio)
44894524
return;
44904525
}
44914526

4492-
queue_for_each_hw_ctx(q, hctx_array, cnt, dio);
4527+
blk_mq_queue_tag_busy_iter(q, hctx_array, cnt, dio);
44934528

44944529
FREEBUF(hctx_array);
44954530
}
@@ -4914,6 +4949,9 @@ void diskio_init(void)
49144949
MEMBER_SIZE_INIT(class_private_devices, "class_private",
49154950
"class_devices");
49164951
MEMBER_OFFSET_INIT(disk_stats_in_flight, "disk_stats", "in_flight");
4952+
MEMBER_OFFSET_INIT(request_queue_tag_set, "request_queue", "tag_set");
4953+
MEMBER_OFFSET_INIT(blk_mq_tag_set_flags, "blk_mq_tag_set", "flags");
4954+
MEMBER_OFFSET_INIT(blk_mq_tag_set_shared_tags, "blk_mq_tag_set", "shared_tags");
49174955

49184956
dt->flags |= DISKIO_INIT;
49194957
}

symbols.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11487,6 +11487,12 @@ dump_offset_table(char *spec, ulong makestruct)
1148711487
OFFSET(blk_mq_tags_nr_reserved_tags));
1148811488
fprintf(fp, " blk_mq_tags_rqs: %ld\n",
1148911489
OFFSET(blk_mq_tags_rqs));
11490+
fprintf(fp, " request_queue_tag_set: %ld\n",
11491+
OFFSET(request_queue_tag_set));
11492+
fprintf(fp, " blk_mq_tag_set_flags: %ld\n",
11493+
OFFSET(blk_mq_tag_set_flags));
11494+
fprintf(fp, " blk_mq_tag_set_shared_tags: %ld\n",
11495+
OFFSET(blk_mq_tag_set_shared_tags));
1149011496

1149111497
fprintf(fp, " subsys_private_subsys: %ld\n", OFFSET(subsys_private_subsys));
1149211498
fprintf(fp, " subsys_private_klist_devices: %ld\n",

0 commit comments

Comments
 (0)