block/blk-mq-debugfs.c

Source file repositories/reference/linux-study-clean/block/blk-mq-debugfs.c

File Facts

System
Linux kernel
Corpus path
block/blk-mq-debugfs.c
Extension
.c
Size
20931 bytes
Lines
830
Domain
Representative Device Path
Bucket
PCIe NVMe Storage Path
Inferred role
Representative Device Path: operation-table or driver-model contract
Status
pattern implementation candidate

Why This File Exists

Part of the selected hardware vertical slice: PCI discovery, driver binding, NVMe queues, block requests, DMA, interrupts, and completion.

Dependency Surface

Detected Declarations

Annotated Snippet

const struct blk_mq_ops *const mq_ops = rq->q->mq_ops;
	const enum req_op op = req_op(rq);
	const char *op_str = blk_op_str(op);

	BUILD_BUG_ON(ARRAY_SIZE(cmd_flag_name) != __REQ_NR_BITS);
	BUILD_BUG_ON(ARRAY_SIZE(rqf_name) != __RQF_BITS);

	seq_printf(m, "%p {.op=", rq);
	if (strcmp(op_str, "UNKNOWN") == 0)
		seq_printf(m, "%u", op);
	else
		seq_printf(m, "%s", op_str);
	seq_puts(m, ", .cmd_flags=");
	blk_flags_show(m, (__force unsigned int)(rq->cmd_flags & ~REQ_OP_MASK),
		       cmd_flag_name, ARRAY_SIZE(cmd_flag_name));
	seq_puts(m, ", .rq_flags=");
	blk_flags_show(m, (__force unsigned int)rq->rq_flags, rqf_name,
		       ARRAY_SIZE(rqf_name));
	seq_printf(m, ", .state=%s", blk_mq_rq_state_name(blk_mq_rq_state(rq)));
	seq_printf(m, ", .tag=%d, .internal_tag=%d", rq->tag,
		   rq->internal_tag);
	if (mq_ops->show_rq)
		mq_ops->show_rq(m, rq);
	seq_puts(m, "}\n");
	return 0;
}
EXPORT_SYMBOL_GPL(__blk_mq_debugfs_rq_show);

int blk_mq_debugfs_rq_show(struct seq_file *m, void *v)
{
	return __blk_mq_debugfs_rq_show(m, list_entry_rq(v));
}
EXPORT_SYMBOL_GPL(blk_mq_debugfs_rq_show);

#define TO_HCTX(m) ((struct blk_mq_hw_ctx *)m->private)

static void *hctx_dispatch_start(struct seq_file *m, loff_t *pos)
	__acquires(&TO_HCTX(m)->lock)
{
	struct blk_mq_hw_ctx *hctx = m->private;

	spin_lock(&hctx->lock);
	return seq_list_start(&hctx->dispatch, *pos);
}

static void *hctx_dispatch_next(struct seq_file *m, void *v, loff_t *pos)
{
	struct blk_mq_hw_ctx *hctx = m->private;

	return seq_list_next(v, &hctx->dispatch, pos);
}

static void hctx_dispatch_stop(struct seq_file *m, void *v)
	__releases(&TO_HCTX(m)->lock)
{
	struct blk_mq_hw_ctx *hctx = m->private;

	spin_unlock(&hctx->lock);
}

#undef TO_HCTX

static const struct seq_operations hctx_dispatch_seq_ops = {
	.start	= hctx_dispatch_start,
	.next	= hctx_dispatch_next,
	.stop	= hctx_dispatch_stop,
	.show	= blk_mq_debugfs_rq_show,
};

struct show_busy_params {
	struct seq_file		*m;
	struct blk_mq_hw_ctx	*hctx;
};

/*
 * Note: the state of a request may change while this function is in progress,
 * e.g. due to a concurrent blk_mq_finish_request() call. Returns true to
 * keep iterating requests.
 */
static bool hctx_show_busy_rq(struct request *rq, void *data)
{
	const struct show_busy_params *params = data;

	if (rq->mq_hctx == params->hctx)
		__blk_mq_debugfs_rq_show(params->m, rq);

	return true;
}

static int hctx_busy_show(void *data, struct seq_file *m)

Annotation

Implementation Notes