Enable lock context analysis for the block layer core
Subsystems (3)
v7 cover Enable lock context analysis for the block layer core
Hi Jens,
Recently the following patch series has been merged: [PATCH v5 00/36] Compiler-Based Context- and Locking-Analysis
(https://lore.kernel.org/lkml/[email protected]/). That patch series drops support for verifying lock context annotations with sparse and introduces support for verifying lock context annotations with Clang. The support in Clang for lock context annotation and verification is better than that in sparse. As an example, __cond_acquires() and __guarded_by() are supported by Clang but not by sparse. Hence this patch series that enables lock context analysis for the block layer core.
Note: although the Linux kernel documentation specifies 22 as minimal version for Clang for context analysis support, this patch series requires Clang 23 because it annotates function pointers. As one can see here, a patch has been queued that fixes the kernel documentation:
https://lore.kernel.org/all/177926568868.711.3058599932884307249.tip-bot2@tip-bot2/
Please consider this patch series for the next merge window.
Thanks,
Bart.
Changes compared to v6:
- In patch 10/14, change guard()() back to spin_lock() calls.
Changes compared to v5:
- Made the description of patch "block/cgroup: Inline blkg_conf_{open,close}_bdev_frozen()" more clear.
- Combined two error paths in ioc_qos_write().
- Folded iocg_lock() and iocg_unlock() into their callers. Removed the token context lock "ioc_lock".
- Introduced macros in the debugfs code that capture expressions with pointer casts.
- Added two patches: "block/blk-iocost: Combine two error paths in ioc_qos_write()" and "block/blk-iocost: Split ioc_rqos_throttle()".
Changes compared to v4:
- Rebased and retested on top of Jens' latest for-next branch.
Changes compared to v3:
- Replaced the "block/bdev: Annotate the blk_holder_ops callback invocations" patch with a patch that adds __releases() annotations to the function pointers in struct blk_holder_ops.
- Dropped the blk-zoned patch since a better patch from Christoph has been merged.
Changes compared to v2:
- Retained the block layer core patches and left out the block driver patches.
- Inlined blkg_conf_open_bdev_frozen() and blkg_conf_close_bdev_frozen().
- In blkg_conf_open_bdev(), added a return statement if the WARN_ON_ONCE() statement triggers.
- Replaced the "block/ioctl: Add lock context annotations" patch with a __release() annotation.
- Replaced the blk-zoned patch with a patch from Christoph.
Changes compared to v1:
- Rebased this patch series on top of Jens' for-next branch.
- Included two patches that split blkg_conf_prep() and blkg_conf_exit().
- Modified how patches are split. Split the block layer core patch into multiple patches and moved the CONTEXT_ANALYSIS := y assignments into the block driver patches.
- Made the new source code comments easier to comprehend.
- Introduced macros in the mq-deadline and Kyber I/O schedulers to make the __acquires() expressions easier to read.
- Removed the changes from this series that are not block layer changes.
Bart Van Assche (14):
block: Annotate the queue limits functions
block/bdev: Annotate the blk_holder_ops callback functions block/cgroup: Split blkg_conf_prep()
block/cgroup: Split blkg_conf_exit()
block/cgroup: Improve lock context annotations block/blk-iocost: Combine two error paths in ioc_qos_write() block/cgroup: Inline blkg_conf_{open,close}_bdev_frozen() block/crypto: Annotate the crypto functions block/blk-iocost: Split ioc_rqos_throttle() block/blk-iocost: Inline iocg_lock() and iocg_unlock() block/blk-mq-debugfs: Improve lock context annotations block/Kyber: Make the lock context annotations compatible with Clang block/mq-deadline: Make the lock context annotations compatible with
Clang
block: Enable lock context analysis
block/Makefile | 2 + block/bfq-cgroup.c | 11 +- block/blk-cgroup.c | 98 +++--------- block/blk-cgroup.h | 13 +- block/blk-crypto-profile.c | 2 + block/blk-iocost.c | 306 +++++++++++++++++++++---------------- block/blk-iolatency.c | 19 ++- block/blk-mq-debugfs.c | 24 ++- block/blk-throttle.c | 34 +++-- block/blk.h | 4 + block/kyber-iosched.c | 7 +- block/mq-deadline.c | 12 +- include/linux/blkdev.h | 21 ++- 13 files changed, 297 insertions(+), 256 deletions(-)
PATCH v7 1/14 block: Annotate the queue limits functions
Let the thread-safety checker verify whether every start of a queue limits update is followed by a call to a function that finishes a queue limits update.
--- include/linux/blkdev.h | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
include/linux/blkdev.h +6 -3
@@ -1092,15 +1092,17 @@ static inline unsigned int blk_boundary_sectors_left(sector_t offset,*/ static inline struct queue_limits queue_limits_start_update (struct request_queue *q) + __acquires(&q->limits_lock) {mutex_lock (&q->limits_lock);return q->limits; } int queue_limits_commit_update_frozen(struct request_queue *q, -struct queue_limits *lim); + struct queue_limits *lim) __releases(&q->limits_lock); int queue_limits_commit_update(struct request_queue *q, -struct queue_limits *lim); -int queue_limits_set (struct request_queue *q,struct queue_limits *lim); + struct queue_limits *lim) __releases(&q->limits_lock); +int queue_limits_set(struct request_queue *q, struct queue_limits *lim) + __must_not_hold(&q->limits_lock);int blk_validate_limits (struct queue_limits *lim);/**
@@ -1112,6 +1114,7 @@ int blk_validate_limits(struct queue_limits *lim);* starting update. */ static inline void queue_limits_cancel_update (struct request_queue *q) + __releases(&q->limits_lock) {mutex_unlock (&q->limits_lock); }
Re: [PATCH v7 01/14] block: Annotate the queue limits functions
On 6/5/26 11:00, Bart Van Assche wrote:
Let the thread-safety checker verify whether every start of a queue limits update is followed by a call to a function that finishes a queue limits update.
Looks good.
-ck
PATCH v7 2/14 block/bdev: Annotate the blk_holder_ops callback functions
In reply to Bart Van AsscheThe four callback functions in blk_holder_ops all release the bd_holder_lock. Annotate these functions accordingly.
--- include/linux/blkdev.h | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
include/linux/blkdev.h +8 -4
@@ -1746,22 +1746,26 @@ void blkdev_show(struct seq_file *seqf, off_t offset);#endif struct blk_holder_ops { -void (*mark_dead)(struct block_device *bdev,bool surprise); + void (*mark_dead)(struct block_device *bdev, bool surprise) + __releases(&bdev->bd_holder_lock);/* * Sync the file system mounted on the block device. */ -void (*sync)(struct block_device *bdev); + void (*sync)(struct block_device *bdev) + __releases(&bdev->bd_holder_lock);/* * Freeze the file system mounted on the block device. */ -int (*freeze)(struct block_device *bdev); + int (*freeze)(struct block_device *bdev) + __releases(&bdev->bd_holder_lock);/* * Thaw the file system mounted on the block device. */ -int (*thaw)(struct block_device *bdev); + int (*thaw)(struct block_device *bdev) + __releases(&bdev->bd_holder_lock); };/*
Re: [PATCH v7 02/14] block/bdev: Annotate the blk_holder_ops callback functions
Quoted 6 lines · Bart Van Assche
The four callback functions in
blk_holder_opsall release thebd_holder_lock. Annotate these functions accordingly.Reviewed-by Hannes Reinecke<[email protected]>Reviewed-by Christoph Hellwig<[email protected]>Signed-off-by Bart Van Assche<[email protected]>
Looks good.
-ck
PATCH v7 3/14 block/cgroup: Split blkg_conf_prep()
In reply to Bart Van AsscheMove the blkg_conf_open_bdev() call out of blkg_conf_prep() to make it possible to add lock context annotations to blkg_conf_prep(). Change an if-statement in blkg_conf_open_bdev() into a WARN_ON_ONCE() call. Export blkg_conf_open_bdev() because it is called by the BFQ I/O scheduler and the BFQ I/O scheduler may be built as a kernel module.
--- block/bfq-cgroup.c | 4 ++++ block/blk-cgroup.c | 18 ++++++++---------- block/blk-iocost.c | 4 ++++ 3 files changed, 16 insertions(+), 10 deletions(-)
block/bfq-cgroup.c +4 -0
@@ -1052,6 +1052,10 @@ static ssize_t bfq_io_set_device_weight(struct kernfs_open_file *of,blkg_conf_init (&ctx, buf); + ret =blkg_conf_open_bdev (&ctx); +if (ret) + goto out; + ret =blkg_conf_prep (blkcg, &blkcg_policy_bfq, &ctx);if (ret) goto out;
block/blk-cgroup.c +8 -10
@@ -771,10 +771,7 @@ EXPORT_SYMBOL_GPL(blkg_conf_init);* @ctx->input and get and store the matching bdev in @ctx->bdev. @ctx->body is * set to point past the device node prefix. * -* This function may be called multiple times on @ctx and the extra calls become -* NOOPs. blkg_conf_prep() implicitly calls this function. Use this function -* explicitly if bdev access is needed without resolving the blkcg / policy part -* of @ctx->input. Returns -errno on error. +* Returns: -errno on error. */ int blkg_conf_open_bdev (struct blkg_conf_ctx *ctx) {
@@ -783,8 +780,8 @@ int blkg_conf_open_bdev(struct blkg_conf_ctx *ctx)struct block_device *bdev;int key_len; -if (ctx->bdev) -return 0 ; +if (WARN_ON_ONCE (ctx->bdev)) +return -EINVAL ;if (sscanf (input,"%u:%u%n" , &major, &minor, &key_len) !=2 )return -EINVAL ;
@@ -813,6 +810,8 @@ int blkg_conf_open_bdev(struct blkg_conf_ctx *ctx) ctx->bdev = bdev;return 0 ; } +EXPORT_SYMBOL_GPL (blkg_conf_open_bdev); +/* * Similar to blkg_conf_open_bdev, but additionally freezes the queue, * ensures the correct locking order between freeze queue and q->rq_qos_mutex.
@@ -857,7 +856,7 @@ unsigned long __must_check blkg_conf_open_bdev_frozen(struct blkg_conf_ctx *ctx)* following MAJ:MIN, @ctx->bdev points to the target block device and * @ctx->blkg to the blkg being configured. * -* blkg_conf_open_bdev() may be called on @ctx beforehand. On success, this +* blkg_conf_open_bdev() must be called on @ctx beforehand. On success, this * function returns with queue lock held and must be followed by * blkg_conf_exit(). */
@@ -870,9 +869,8 @@ int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol,struct blkcg_gq *blkg;int ret; - ret =blkg_conf_open_bdev (ctx); -if (ret) -return ret; +if (WARN_ON_ONCE (!ctx->bdev)) +return -EINVAL ; disk = ctx->bdev->bd_disk; q = disk->queue;
block/blk-iocost.c +4 -0
@@ -3140,6 +3140,10 @@ static ssize_t ioc_weight_write(struct kernfs_open_file *of, char *buf,blkg_conf_init (&ctx, buf); + ret =blkg_conf_open_bdev (&ctx); +if (ret) + goto err; + ret =blkg_conf_prep (blkcg, &blkcg_policy_iocost, &ctx);if (ret) goto err;
Re: [PATCH v7 03/14] block/cgroup: Split blkg_conf_prep()
PATCH v7 4/14 block/cgroup: Split blkg_conf_exit()
In reply to Bart Van AsscheSplit blkg_conf_exit() into blkg_conf_unprep() and blkg_conf_close_bdev() because blkg_conf_exit() is not compatible with the Clang thread-safety annotations. Remove blkg_conf_exit(). Rename blkg_conf_exit_frozen() into blkg_conf_close_bdev_frozen(). Add thread-safety annotations to the new functions.
--- block/bfq-cgroup.c | 9 ++++-- block/blk-cgroup.c | 57 ++++++++++++++++++------------------ block/blk-cgroup.h | 6 ++-- block/blk-iocost.c | 67 +++++++++++++++++++++---------------------- block/blk-iolatency.c | 19 ++++++------ block/blk-throttle.c | 34 +++++++++++++--------- 6 files changed, 101 insertions(+), 91 deletions(-)
block/bfq-cgroup.c +6 -3
@@ -1054,11 +1054,11 @@ static ssize_t bfq_io_set_device_weight(struct kernfs_open_file *of, ret =blkg_conf_open_bdev (&ctx);if (ret) - goto out; +return ret; ret =blkg_conf_prep (blkcg, &blkcg_policy_bfq, &ctx);if (ret) - goto out; + goto close_bdev;if (sscanf (ctx.body,"%llu" , &v) ==1 ) {/* require "default" on dfl */
@@ -1079,8 +1079,11 @@ static ssize_t bfq_io_set_device_weight(struct kernfs_open_file *of,bfq_group_set_weight (bfqg, bfqg->entity.weight, v); ret =0 ; } + out: -blkg_conf_exit (&ctx); +blkg_conf_unprep (&ctx); +close_bdev: +blkg_conf_close_bdev (&ctx);return ret ?: nbytes; }
block/blk-cgroup.c +28 -29
92 lines not on this page · raw message
block/blk-cgroup.h +4 -2
@@ -222,8 +222,10 @@ int blkg_conf_open_bdev(struct blkg_conf_ctx *ctx);unsigned long blkg_conf_open_bdev_frozen (struct blkg_conf_ctx *ctx);int blkg_conf_prep (struct blkcg *blkcg,const struct blkcg_policy *pol,struct blkg_conf_ctx *ctx); -void blkg_conf_exit (struct blkg_conf_ctx *ctx); -void blkg_conf_exit_frozen (struct blkg_conf_ctx *ctx,unsigned long memflags); +void blkg_conf_unprep (struct blkg_conf_ctx *ctx); +void blkg_conf_close_bdev (struct blkg_conf_ctx *ctx); +void blkg_conf_close_bdev_frozen (struct blkg_conf_ctx *ctx, +unsigned long memflags);/** * bio_issue_as_root_blkg - see if this bio needs to be issued as root blkg
block/blk-iocost.c +32 -35
161 lines not on this page · raw message
block/blk-iolatency.c +11 -8
@@ -840,7 +840,7 @@ static ssize_t iolatency_set_limit(struct kernfs_open_file *of, char *buf, ret =blkg_conf_open_bdev (&ctx);if (ret) - goto out; +return ret;/* * blk_iolatency_init() may fail after rq_qos_add() succeeds which can
@@ -850,11 +850,11 @@ static ssize_t iolatency_set_limit(struct kernfs_open_file *of, char *buf,if (!iolat_rq_qos (ctx.bdev->bd_queue)) ret =blk_iolatency_init (ctx.bdev->bd_disk);if (ret) - goto out; + goto close_bdev; ret =blkg_conf_prep (blkcg, &blkcg_policy_iolatency, &ctx);if (ret) - goto out; + goto close_bdev; iolat =blkg_to_lat (ctx.blkg); p = ctx.body;
@@ -865,7 +865,7 @@ static ssize_t iolatency_set_limit(struct kernfs_open_file *of, char *buf,char val[21 ];/* 18446744073709551616 */ if (sscanf (tok,"%15[^=]=%20s" , key, val) !=2 ) - goto out; + goto unprep;if (!strcmp (key,"target" )) {u64 v;
@@ -875,9 +875,9 @@ static ssize_t iolatency_set_limit(struct kernfs_open_file *of, char *buf,else if (sscanf (val,"%llu" , &v) ==1 ) lat_val = v *NSEC_PER_USEC ;else - goto out; + goto unprep; }else { - goto out; + goto unprep; } }
@@ -889,8 +889,11 @@ static ssize_t iolatency_set_limit(struct kernfs_open_file *of, char *buf,if (oldval != iolat->min_lat_nsec)iolatency_clear_scaling (blkg); ret =0 ; -out: -blkg_conf_exit (&ctx); + +unprep: +blkg_conf_unprep (&ctx); +close_bdev: +blkg_conf_close_bdev (&ctx);return ret ?: nbytes; }
block/blk-throttle.c +20 -14
@@ -1353,21 +1353,21 @@ static ssize_t tg_set_conf(struct kernfs_open_file *of, ret =blkg_conf_open_bdev (&ctx);if (ret) - goto out_finish; +return ret;if (!blk_throtl_activated (ctx.bdev->bd_queue)) { ret =blk_throtl_init (ctx.bdev->bd_disk);if (ret) - goto out_finish; + goto close_bdev; } ret =blkg_conf_prep (blkcg, &blkcg_policy_throtl, &ctx);if (ret) - goto out_finish; + goto close_bdev; ret = -EINVAL ;if (sscanf (ctx.body,"%llu" , &v) !=1 ) - goto out_finish; + goto unprep;if (!v) v =U64_MAX ;
@@ -1381,8 +1381,12 @@ static ssize_t tg_set_conf(struct kernfs_open_file *of,tg_conf_updated (tg, false); ret =0 ; -out_finish: -blkg_conf_exit (&ctx); + +unprep: +blkg_conf_unprep (&ctx); + +close_bdev: +blkg_conf_close_bdev (&ctx);return ret ?: nbytes; }
@@ -1537,17 +1541,17 @@ static ssize_t tg_set_limit(struct kernfs_open_file *of, ret =blkg_conf_open_bdev (&ctx);if (ret) - goto out_finish; +return ret;if (!blk_throtl_activated (ctx.bdev->bd_queue)) { ret =blk_throtl_init (ctx.bdev->bd_disk);if (ret) - goto out_finish; + goto close_bdev; } ret =blkg_conf_prep (blkcg, &blkcg_policy_throtl, &ctx);if (ret) - goto out_finish; + goto close_bdev; tg =blkg_to_tg (ctx.blkg);tg_update_carryover (tg);
@@ -1573,11 +1577,11 @@ static ssize_t tg_set_limit(struct kernfs_open_file *of, p = tok;strsep (&p,"=" );if (!p || (sscanf (p,"%llu" , &val) !=1 &&strcmp (p,"max" ))) - goto out_finish; + goto unprep; ret = -ERANGE ;if (!val) - goto out_finish; + goto unprep; ret = -EINVAL ;if (!strcmp (tok,"rbps" ))
@@ -1589,7 +1593,7 @@ static ssize_t tg_set_limit(struct kernfs_open_file *of,else if (!strcmp (tok,"wiops" )) v[3 ] =min_t (u64, val,UINT_MAX );else - goto out_finish; + goto unprep; } tg->bps[READ ] = v[0 ];
@@ -1599,8 +1603,10 @@ static ssize_t tg_set_limit(struct kernfs_open_file *of,tg_conf_updated (tg, false); ret =0 ; -out_finish: -blkg_conf_exit (&ctx); +unprep: +blkg_conf_unprep (&ctx); +close_bdev: +blkg_conf_close_bdev (&ctx);return ret ?: nbytes; }
Re: [PATCH v7 04/14] block/cgroup: Split blkg_conf_exit()
PATCH v7 5/14 block/cgroup: Improve lock context annotations
In reply to Bart Van AsscheAdd lock context annotations where these are missing. Move the blkg_conf_prep() annotation into block/blk-cgroup.h to make it visible to all blkg_conf_prep() callers.
--- block/blk-cgroup.c | 1 - block/blk-cgroup.h | 15 ++++++++++----- 2 files changed, 10 insertions(+), 6 deletions(-)
block/blk-cgroup.c +0 -1
@@ -862,7 +862,6 @@ unsigned long __must_check blkg_conf_open_bdev_frozen(struct blkg_conf_ctx *ctx)*/ int blkg_conf_prep (struct blkcg *blkcg,const struct blkcg_policy *pol,struct blkg_conf_ctx *ctx) - __acquires(&bdev->bd_queue->queue_lock) {struct gendisk *disk;struct request_queue *q;
block/blk-cgroup.h +10 -5
@@ -218,14 +218,19 @@ struct blkg_conf_ctx { };void blkg_conf_init (struct blkg_conf_ctx *ctx,char *input); -int blkg_conf_open_bdev (struct blkg_conf_ctx *ctx); +int blkg_conf_open_bdev(struct blkg_conf_ctx *ctx) + __cond_acquires(0, &ctx->bdev->bd_queue->rq_qos_mutex);unsigned long blkg_conf_open_bdev_frozen (struct blkg_conf_ctx *ctx); int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol, -struct blkg_conf_ctx *ctx); -void blkg_conf_unprep (struct blkg_conf_ctx *ctx); -void blkg_conf_close_bdev (struct blkg_conf_ctx *ctx); + struct blkg_conf_ctx *ctx) + __cond_acquires(0, &ctx->bdev->bd_disk->queue->queue_lock); +void blkg_conf_unprep(struct blkg_conf_ctx *ctx) + __releases(ctx->bdev->bd_disk->queue->queue_lock); +void blkg_conf_close_bdev(struct blkg_conf_ctx *ctx) + __releases(&ctx->bdev->bd_queue->rq_qos_mutex); void blkg_conf_close_bdev_frozen(struct blkg_conf_ctx *ctx, -unsigned long memflags); + unsigned long memflags) + __releases(&ctx->bdev->bd_queue->rq_qos_mutex);/** * bio_issue_as_root_blkg - see if this bio needs to be issued as root blkg
Re: [PATCH v7 05/14] block/cgroup: Improve lock context annotations
PATCH v7 6/14 block/blk-iocost: Combine two error paths in ioc_qos_write()
In reply to Bart Van AsscheReduce code duplication by combining two error paths. No functionality has been changed.
--- block/blk-iocost.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
block/blk-iocost.c +7 -7
@@ -3239,7 +3239,7 @@ static ssize_t ioc_qos_write(struct kernfs_open_file *of, char *input,bool enable, user;char *body, *p;unsigned long memflags; -int ret; +int ret =0 ;blkg_conf_init (&ctx, input);
@@ -3251,14 +3251,14 @@ static ssize_t ioc_qos_write(struct kernfs_open_file *of, char *input, disk = ctx.bdev->bd_disk;if (!queue_is_mq (disk->queue)) { ret = -EOPNOTSUPP ; - goto err; + goto close_bdev; } ioc =q_to_ioc (disk->queue);if (!ioc) { ret =blk_iocost_init (disk);if (ret) - goto err; + goto close_bdev; ioc =q_to_ioc (disk->queue); }
@@ -3362,15 +3362,15 @@ static ssize_t ioc_qos_write(struct kernfs_open_file *of, char *input,blk_mq_unquiesce_queue (disk->queue); +close_bdev:blkg_conf_close_bdev_frozen (&ctx, memflags); -return nbytes; +return ret ?: nbytes; + einval:spin_unlock_irq (&ioc->lock);blk_mq_unquiesce_queue (disk->queue); ret = -EINVAL ; -err: -blkg_conf_close_bdev_frozen (&ctx, memflags); -return ret; + goto close_bdev; } static u64 ioc_cost_model_prfill(struct seq_file *sf,
Re: [PATCH v7 06/14] block/blk-iocost: Combine two error paths in ioc_qos_write()
PATCH v7 7/14 block/cgroup: Inline blkg_conf_{open,close}_bdev_frozen()
In reply to Bart Van AsscheThe blkg_conf_open_bdev_frozen() calling convention is not compatible with lock context annotations. Fold both blkg_conf_open_bdev_frozen() and blkg_conf_close_bdev_frozen() into their only caller. This patch prepares for enabling lock context analysis.
The type of 'memflags' has been changed from unsigned long into unsigned int to match the type of current->flags. See also <linux/sched.h>.
--- block/blk-cgroup.c | 46 ---------------------------------------------- block/blk-cgroup.h | 4 ---- block/blk-iocost.c | 25 +++++++++++++++++++------ 3 files changed, 19 insertions(+), 56 deletions(-)
block/blk-cgroup.c +0 -46
@@ -812,39 +812,6 @@ int blkg_conf_open_bdev(struct blkg_conf_ctx *ctx) }EXPORT_SYMBOL_GPL (blkg_conf_open_bdev); -/* -* Similar to blkg_conf_open_bdev, but additionally freezes the queue, -* ensures the correct locking order between freeze queue and q->rq_qos_mutex. -* -* This function returns negative error on failure. On success it returns -* memflags which must be saved and later passed to -* blkg_conf_close_bdev_frozen() for restoring the memalloc scope. -*/ -unsigned long __must_check blkg_conf_open_bdev_frozen (struct blkg_conf_ctx *ctx) -{ -int ret; -unsigned long memflags; - -if (ctx->bdev) -return -EINVAL ; - - ret =blkg_conf_open_bdev (ctx); -if (ret <0 ) -return ret; -/* -* At this point, we haven’t started protecting anything related to QoS, -* so we release q->rq_qos_mutex here, which was first acquired in blkg_ -* conf_open_bdev. Later, we re-acquire q->rq_qos_mutex after freezing -* the queue to maintain the correct locking order. -*/ -mutex_unlock (&ctx->bdev->bd_queue->rq_qos_mutex); - - memflags =blk_mq_freeze_queue (ctx->bdev->bd_queue); -mutex_lock (&ctx->bdev->bd_queue->rq_qos_mutex); - -return memflags; -} -/** * blkg_conf_prep - parse and prepare for per-blkg config update * @blkcg: target block cgroup
@@ -991,19 +958,6 @@ void blkg_conf_close_bdev(struct blkg_conf_ctx *ctx) }EXPORT_SYMBOL_GPL (blkg_conf_close_bdev); -/* -* Similar to blkg_close_bdev, but also unfreezes the queue. Should be used -* when blkg_conf_open_bdev_frozen is used to open the bdev. -*/ -void blkg_conf_close_bdev_frozen (struct blkg_conf_ctx *ctx, -unsigned long memflags) -{ -struct request_queue *q = ctx->bdev->bd_queue; - -blkg_conf_close_bdev (ctx); -blk_mq_unfreeze_queue (q, memflags); -} -static void blkg_iostat_add (struct blkg_iostat *dst,struct blkg_iostat *src) {int i;
block/blk-cgroup.h +0 -4
@@ -220,7 +220,6 @@ struct blkg_conf_ctx {void blkg_conf_init (struct blkg_conf_ctx *ctx,char *input); int blkg_conf_open_bdev(struct blkg_conf_ctx *ctx) __cond_acquires(0, &ctx->bdev->bd_queue->rq_qos_mutex); -unsigned long blkg_conf_open_bdev_frozen (struct blkg_conf_ctx *ctx); int blkg_conf_prep(struct blkcg *blkcg, const struct blkcg_policy *pol, struct blkg_conf_ctx *ctx) __cond_acquires(0, &ctx->bdev->bd_disk->queue->queue_lock);
@@ -228,9 +227,6 @@ void blkg_conf_unprep(struct blkg_conf_ctx *ctx)__releases (ctx->bdev->bd_disk->queue->queue_lock); void blkg_conf_close_bdev(struct blkg_conf_ctx *ctx) __releases(&ctx->bdev->bd_queue->rq_qos_mutex); -void blkg_conf_close_bdev_frozen(struct blkg_conf_ctx *ctx, - unsigned long memflags) - __releases(&ctx->bdev->bd_queue->rq_qos_mutex);/** * bio_issue_as_root_blkg - see if this bio needs to be issued as root blkg
block/blk-iocost.c +19 -6
@@ -3233,19 +3233,30 @@ static ssize_t ioc_qos_write(struct kernfs_open_file *of, char *input, size_t nbytes, loff_t off) {struct blkg_conf_ctx ctx; +struct request_queue *q;struct gendisk *disk;struct ioc *ioc;u32 qos[NR_QOS_PARAMS ];bool enable, user;char *body, *p; -unsigned long memflags; -int ret =0 ; +unsigned int memflags; +int ret;blkg_conf_init (&ctx, input); - memflags =blkg_conf_open_bdev_frozen (&ctx); -if (IS_ERR_VALUE (memflags)) -return memflags; + ret =blkg_conf_open_bdev (&ctx); +if (ret) +return ret; +/* +* At this point, we haven’t started protecting anything related to QoS, +* so we release q->rq_qos_mutex here, which was first acquired in blkg_ +* conf_open_bdev. Later, we re-acquire q->rq_qos_mutex after freezing +* the queue to maintain the correct locking order. +*/ +mutex_unlock (&ctx.bdev->bd_queue->rq_qos_mutex); + + memflags =blk_mq_freeze_queue (ctx.bdev->bd_queue); +mutex_lock (&ctx.bdev->bd_queue->rq_qos_mutex); body = ctx.body; disk = ctx.bdev->bd_disk;
@@ -3363,7 +3374,9 @@ static ssize_t ioc_qos_write(struct kernfs_open_file *of, char *input,blk_mq_unquiesce_queue (disk->queue); close_bdev: -blkg_conf_close_bdev_frozen (&ctx, memflags); + q = ctx.bdev->bd_queue; +blkg_conf_close_bdev (&ctx); +blk_mq_unfreeze_queue (q, memflags);return ret ?: nbytes; einval:
Re: [PATCH v7 07/14] block/cgroup: Inline blkg_conf_{open,close}_bdev_frozen()
PATCH v7 8/14 block/crypto: Annotate the crypto functions
In reply to Bart Van AsscheAdd the lock context annotations required for Clang's thread-safety analysis.
--- block/blk-crypto-profile.c | 2 ++ 1 file changed, 2 insertions(+)
block/blk-crypto-profile.c +2 -0
@@ -43,6 +43,7 @@ struct blk_crypto_keyslot { };static inline void blk_crypto_hw_enter (struct blk_crypto_profile *profile) + __acquires(&profile->lock) {/* * Calling into the driver requires profile->lock held and the device
@@ -55,6 +56,7 @@ static inline void blk_crypto_hw_enter(struct blk_crypto_profile *profile) }static inline void blk_crypto_hw_exit (struct blk_crypto_profile *profile) + __releases(&profile->lock) {up_write (&profile->lock);if (profile->dev)
PATCH v7 9/14 block/blk-iocost: Split ioc_rqos_throttle()
In reply to Bart Van AsschePrepare for inlining iocg_lock() and iocg_unlock() by moving the code between these two calls into a new function. No functionality has been changed.
--- block/blk-iocost.c | 163 ++++++++++++++++++++++++++------------------- 1 file changed, 94 insertions(+), 69 deletions(-)
block/blk-iocost.c +94 -69
@@ -2614,6 +2614,88 @@ static u64 calc_size_vtime_cost(struct request *rq, struct ioc *ioc)return cost; } +enum over_budget_action { + action_retry, + action_commit, + action_wait, + action_return, +}; + +static enum over_budget_action +iocg_handle_over_budget (struct rq_qos *rqos,struct ioc_gq *iocg, +struct bio *bio,struct ioc_now *now, +struct iocg_wait *wait,bool use_debt,bool ioc_locked, +u64 abs_cost,u64 cost) +{ +lockdep_assert_held (&iocg->waitq.lock); + +/* +* @iocg must stay activated for debt and waitq handling. Deactivation +* is synchronized against both ioc->lock and waitq.lock and we won't +* get deactivated as long as we're waiting or have debt, so we're good +* if we're activated here. In the unlikely cases that we aren't, just +* issue the IO. +*/ +if (unlikely (list_empty (&iocg->active_list))) +return action_commit; + +/* +* We're over budget. If @bio has to be issued regardless, remember +* the abs_cost instead of advancing vtime. iocg_kick_waitq() will pay +* off the debt before waking more IOs. +* +* This way, the debt is continuously paid off each period with the +* actual budget available to the cgroup. If we just wound vtime, we +* would incorrectly use the current hw_inuse for the entire amount +* which, for example, can lead to the cgroup staying blocked for a +* long time even with substantially raised hw_inuse. +* +* An iocg with vdebt should stay online so that the timer can keep +* deducting its vdebt and [de]activate use_delay mechanism +* accordingly. We don't want to race against the timer trying to +* clear them and leave @iocg inactive w/ dangling use_delay heavily +* penalizing the cgroup and its descendants. +*/ +if (use_debt) { +iocg_incur_debt (iocg, abs_cost, now); +if (iocg_kick_delay (iocg, now)) +blkcg_schedule_throttle (rqos->disk, + (bio->bi_opf &REQ_SWAP ) == +REQ_SWAP ); +return action_return; + } + +/* guarantee that iocgs w/ waiters have maximum inuse */ +if (!iocg->abs_vdebt && iocg->inuse != iocg->active) { +if (!ioc_locked) +return action_retry; +lockdep_assert_held (&iocg->ioc->lock); +propagate_weights (iocg, iocg->active, iocg->active, true, now); + } + +/* +* Append self to the waitq and schedule the wakeup timer if we're +* the first waiter. The timer duration is calculated based on the +* current vrate. vtime and hweight changes can make it too short +* or too long. Each wait entry records the absolute cost it's +* waiting for to allow re-evaluation using a custom wait entry. +* +* If too short, the timer simply reschedules itself. If too long, +* the period timer will notice and trigger wakeups. +* +* All waiters are on iocg->waitq and the wait states are +* synchronized using waitq.lock. +*/ +init_wait_func (&wait->wait, iocg_wake_fn); + wait->bio = bio; + wait->abs_cost = abs_cost; + wait->committed = false;/* will be set true by waker */ + +__add_wait_queue_entry_tail (&iocg->waitq, &wait->wait); +iocg_kick_waitq (iocg, ioc_locked, now); +return action_wait; +} +static void ioc_rqos_throttle (struct rq_qos *rqos,struct bio *bio) {struct blkcg_gq *blkg = bio->bi_blkg;
@@ -2623,6 +2705,7 @@ static void ioc_rqos_throttle(struct rq_qos *rqos, struct bio *bio)struct iocg_wait wait;u64 abs_cost, cost, vtime;bool use_debt, ioc_locked; +enum over_budget_action action;unsigned long flags;/* bypass IOs if disabled, still initializing, or for root cgroup */
@@ -2663,80 +2746,22 @@ static void ioc_rqos_throttle(struct rq_qos *rqos, struct bio *bio) ioc_locked = use_debt ||READ_ONCE (iocg->abs_vdebt); retry_lock:iocg_lock (iocg, ioc_locked, &flags); - -/* -* @iocg must stay activated for debt and waitq handling. Deactivation -* is synchronized against both ioc->lock and waitq.lock and we won't -* get deactivated as long as we're waiting or has debt, so we're good -* if we're activated here. In the unlikely cases that we aren't, just -* issue the IO. -*/ -if (unlikely (list_empty (&iocg->active_list))) { -iocg_unlock (iocg, ioc_locked, &flags); + action =iocg_handle_over_budget (rqos, iocg, bio, &now, &wait, use_debt, + ioc_locked, abs_cost, cost); +iocg_unlock (iocg, ioc_locked, &flags); +switch (action) { +case action_retry: + ioc_locked = true; + goto retry_lock; +case action_commit:iocg_commit_bio (iocg, bio, abs_cost, cost);return ; - } - -/* -* We're over budget. If @bio has to be issued regardless, remember -* the abs_cost instead of advancing vtime. iocg_kick_waitq() will pay -* off the debt before waking more IOs. -* -* This way, the debt is continuously paid off each period with the -* actual budget available to the cgroup. If we just wound vtime, we -* would incorrectly use the current hw_inuse for the entire amount -* which, for example, can lead to the cgroup staying blocked for a -* long time even with substantially raised hw_inuse. -* -* An iocg with vdebt should stay online so that the timer can keep -* deducting its vdebt and [de]activate use_delay mechanism -* accordingly. We don't want to race against the timer trying to -* clear them and leave @iocg inactive w/ dangling use_delay heavily -* penalizing the cgroup and its descendants. -*/ -if (use_debt) { -iocg_incur_debt (iocg, abs_cost, &now); -if (iocg_kick_delay (iocg, &now)) -blkcg_schedule_throttle (rqos->disk, - (bio->bi_opf &REQ_SWAP ) ==REQ_SWAP ); -iocg_unlock (iocg, ioc_locked, &flags); +case action_return:return ; +case action_wait: +break ; } -/* guarantee that iocgs w/ waiters have maximum inuse */ -if (!iocg->abs_vdebt && iocg->inuse != iocg->active) { -if (!ioc_locked) { -iocg_unlock (iocg, false, &flags); - ioc_locked = true; - goto retry_lock; - } -propagate_weights (iocg, iocg->active, iocg->active, true, - &now); - } - -/* -* Append self to the waitq and schedule the wakeup timer if we're -* the first waiter. The timer duration is calculated based on the -* current vrate. vtime and hweight changes can make it too short -* or too long. Each wait entry records the absolute cost it's -* waiting for to allow re-evaluation using a custom wait entry. -* -* If too short, the timer simply reschedules itself. If too long, -* the period timer will notice and trigger wakeups. -* -* All waiters are on iocg->waitq and the wait states are -* synchronized using waitq.lock. -*/ -init_wait_func (&wait.wait, iocg_wake_fn); - wait.bio = bio; - wait.abs_cost = abs_cost; - wait.committed = false;/* will be set true by waker */ - -__add_wait_queue_entry_tail (&iocg->waitq, &wait.wait); -iocg_kick_waitq (iocg, ioc_locked, &now); - -iocg_unlock (iocg, ioc_locked, &flags); -while (true) {set_current_state (TASK_UNINTERRUPTIBLE );if (wait.committed)
Re: [PATCH v7 09/14] block/blk-iocost: Split ioc_rqos_throttle()
PATCH v7 10/14 block/blk-iocost: Inline iocg_lock() and iocg_unlock()
In reply to Bart Van AsscheBoth iocg_lock() and iocg_unlock() use conditional locking. Fold these functions into their callers such that unlocking becomes unconditional.
--- block/blk-iocost.c | 53 +++++++++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 27 deletions(-)
block/blk-iocost.c +26 -27
@@ -727,26 +727,6 @@ static void iocg_commit_bio(struct ioc_gq *iocg, struct bio *bio,put_cpu_ptr (gcs); } -static void iocg_lock (struct ioc_gq *iocg,bool lock_ioc,unsigned long *flags) -{ -if (lock_ioc) { -spin_lock_irqsave (&iocg->ioc->lock, *flags); -spin_lock (&iocg->waitq.lock); - }else { -spin_lock_irqsave (&iocg->waitq.lock, *flags); - } -} - -static void iocg_unlock (struct ioc_gq *iocg,bool unlock_ioc,unsigned long *flags) -{ -if (unlock_ioc) { -spin_unlock (&iocg->waitq.lock); -spin_unlock_irqrestore (&iocg->ioc->lock, *flags); - }else { -spin_unlock_irqrestore (&iocg->waitq.lock, *flags); - } -} -#define CREATE_TRACE_POINTS #include <trace/events/iocost.h>
@@ -1589,9 +1569,17 @@ static enum hrtimer_restart iocg_waitq_timer_fn(struct hrtimer *timer)ioc_now (iocg->ioc, &now); -iocg_lock (iocg, pay_debt, &flags); -iocg_kick_waitq (iocg, pay_debt, &now); -iocg_unlock (iocg, pay_debt, &flags); +if (pay_debt) { +spin_lock_irqsave (&iocg->ioc->lock, flags); +spin_lock (&iocg->waitq.lock); +iocg_kick_waitq (iocg, pay_debt, &now); +spin_unlock (&iocg->waitq.lock); +spin_unlock_irqrestore (&iocg->ioc->lock, flags); + }else { +spin_lock_irqsave (&iocg->waitq.lock, flags); +iocg_kick_waitq (iocg, pay_debt, &now); +spin_unlock_irqrestore (&iocg->waitq.lock, flags); + }return HRTIMER_NORESTART ; }
@@ -2745,10 +2733,21 @@ static void ioc_rqos_throttle(struct rq_qos *rqos, struct bio *bio) use_debt =bio_issue_as_root_blkg (bio) ||fatal_signal_pending (current); ioc_locked = use_debt ||READ_ONCE (iocg->abs_vdebt); retry_lock: -iocg_lock (iocg, ioc_locked, &flags); - action =iocg_handle_over_budget (rqos, iocg, bio, &now, &wait, use_debt, - ioc_locked, abs_cost, cost); -iocg_unlock (iocg, ioc_locked, &flags); +if (ioc_locked) { +spin_lock_irqsave (&iocg->ioc->lock, flags); +spin_lock (&iocg->waitq.lock); + action =iocg_handle_over_budget (rqos, iocg, bio, &now, &wait, + use_debt, ioc_locked, abs_cost, + cost); +spin_unlock (&iocg->waitq.lock); +spin_unlock_irqrestore (&iocg->ioc->lock, flags); + }else { +spin_lock_irqsave (&iocg->waitq.lock, flags); + action =iocg_handle_over_budget (rqos, iocg, bio, &now, &wait, + use_debt, ioc_locked, abs_cost, + cost); +spin_unlock_irqrestore (&iocg->waitq.lock, flags); + }switch (action) {case action_retry: ioc_locked = true;
Re: [PATCH v7 10/14] block/blk-iocost: Inline iocg_lock() and iocg_unlock()
PATCH v7 11/14 block/blk-mq-debugfs: Improve lock context annotations
In reply to Bart Van AsscheMake the existing lock context annotations compatible with Clang. Add the lock context annotations that are missing.
--- block/blk-mq-debugfs.c | 24 ++++++++++++++++++------ block/blk.h | 4 ++++ 2 files changed, 22 insertions(+), 6 deletions(-)
block/blk-mq-debugfs.c +18 -6
@@ -19,8 +19,10 @@ static int queue_poll_stat_show(void *data, struct seq_file *m)return 0 ; } +#define TO_REQUEST_QUEUE (m) ((struct request_queue *)m->private) +static void *queue_requeue_list_start (struct seq_file *m,loff_t *pos) - __acquires(&q->requeue_lock) + __acquires(&TO_REQUEST_QUEUE(m)->requeue_lock) {struct request_queue *q = m->private;
@@ -36,13 +38,15 @@ static void *queue_requeue_list_next(struct seq_file *m, void *v, loff_t *pos) }static void queue_requeue_list_stop (struct seq_file *m,void *v) - __releases(&q->requeue_lock) + __releases(&TO_REQUEST_QUEUE(m)->requeue_lock) {struct request_queue *q = m->private;spin_unlock_irq (&q->requeue_lock); } +#undef TO_REQUEST_QUEUE +static const struct seq_operations queue_requeue_list_seq_ops = { .start = queue_requeue_list_start, .next = queue_requeue_list_next,
@@ -297,8 +301,10 @@ int blk_mq_debugfs_rq_show(struct seq_file *m, void *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(&hctx->lock) + __acquires(&TO_HCTX(m)->lock) {struct blk_mq_hw_ctx *hctx = m->private;
@@ -314,13 +320,15 @@ static void *hctx_dispatch_next(struct seq_file *m, void *v, loff_t *pos) }static void hctx_dispatch_stop (struct seq_file *m,void *v) - __releases(&hctx->lock) + __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,
@@ -484,9 +492,11 @@ static int hctx_dispatch_busy_show(void *data, struct seq_file *m)return 0 ; } +#define TO_CTX (m) ((struct blk_mq_ctx *)m->private) +#define CTX_RQ_SEQ_OPS (name, type) \ static void *ctx_##name##_rq_list_start(struct seq_file *m, loff_t *pos) \ - __acquires(&ctx->lock) \ + __acquires(&TO_CTX(m)->lock) \ { \ struct blk_mq_ctx *ctx = m->private; \ \
@@ -503,7 +513,7 @@ static void *ctx_##name##_rq_list_next(struct seq_file *m, void *v, \ } \ \ static void ctx_##name##_rq_list_stop(struct seq_file *m, void *v) \ - __releases(&ctx->lock) \ + __releases(&TO_CTX(m)->lock) \ { \ struct blk_mq_ctx *ctx = m->private; \ \
@@ -521,6 +531,8 @@ CTX_RQ_SEQ_OPS(default, HCTX_TYPE_DEFAULT);CTX_RQ_SEQ_OPS (read,HCTX_TYPE_READ );CTX_RQ_SEQ_OPS (poll,HCTX_TYPE_POLL ); +#undef TO_CTX +static int blk_mq_debugfs_show (struct seq_file *m,void *v) {const struct blk_mq_debugfs_attr *attr = m->private;
block/blk.h +4 -0
@@ -756,16 +756,19 @@ static inline void blk_unfreeze_release_lock(struct request_queue *q)* reclaim from triggering block I/O. */ static inline void blk_debugfs_lock_nomemsave (struct request_queue *q) + __acquires(&q->debugfs_mutex) {mutex_lock (&q->debugfs_mutex); }static inline void blk_debugfs_unlock_nomemrestore (struct request_queue *q) + __releases(&q->debugfs_mutex) {mutex_unlock (&q->debugfs_mutex); }static inline unsigned int __must_check blk_debugfs_lock (struct request_queue *q) + __acquires(&q->debugfs_mutex) {unsigned int memflags =memalloc_noio_save ();
@@ -775,6 +778,7 @@ static inline unsigned int __must_check blk_debugfs_lock(struct request_queue *qstatic inline void blk_debugfs_unlock (struct request_queue *q,unsigned int memflags) + __releases(&q->debugfs_mutex) {blk_debugfs_unlock_nomemrestore (q);memalloc_noio_restore (memflags);
Re: [PATCH v7 11/14] block/blk-mq-debugfs: Improve lock context annotations
PATCH v7 12/14 block/Kyber: Make the lock context annotations compatible with Clang
In reply to Bart Van AsscheWhile sparse ignores the __acquires() and __releases() arguments, Clang verifies these. Make the arguments of __acquires() and __releases() acceptable for Clang.
--- block/kyber-iosched.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
block/kyber-iosched.c +5 -2
@@ -882,6 +882,9 @@ static const struct elv_fs_entry kyber_sched_attrs[] = { };#undef KYBER_LAT_ATTR +#define HCTX_FROM_SEQ_FILE (m) ((struct blk_mq_hw_ctx *)(m)->private) +#define KYBER_HCTX_DATA (hctx) ((struct kyber_hctx_data *)(hctx)->sched_data) +#ifdef CONFIG_BLK_DEBUG_FS #define KYBER_DEBUGFS_DOMAIN_ATTRS (domain, name) \ static int kyber_##name##_tokens_show(void *data, struct seq_file *m) \
@@ -894,7 +897,7 @@ static int kyber_##name##_tokens_show(void *data, struct seq_file *m) \ } \ \ static void *kyber_##name##_rqs_start(struct seq_file *m, loff_t *pos) \ - __acquires(&khd->lock) \ + __acquires(&KYBER_HCTX_DATA(HCTX_FROM_SEQ_FILE(m))->lock) \ { \ struct blk_mq_hw_ctx *hctx = m->private; \ struct kyber_hctx_data *khd = hctx->sched_data; \
@@ -913,7 +916,7 @@ static void *kyber_##name##_rqs_next(struct seq_file *m, void *v, \ } \ \ static void kyber_##name##_rqs_stop(struct seq_file *m, void *v) \ - __releases(&khd->lock) \ + __releases(&KYBER_HCTX_DATA(HCTX_FROM_SEQ_FILE(m))->lock) \ { \ struct blk_mq_hw_ctx *hctx = m->private; \ struct kyber_hctx_data *khd = hctx->sched_data; \
Re: [PATCH v7 12/14] block/Kyber: Make the lock context annotations compatible with Clang
PATCH v7 13/14 block/mq-deadline: Make the lock context annotations compatible with Clang
In reply to Bart Van AsscheWhile sparse ignores the __acquires() and __releases() arguments, Clang verifies these. Make the arguments of __acquires() and __releases() acceptable for Clang.
--- block/mq-deadline.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
block/mq-deadline.c +8 -4
@@ -794,11 +794,15 @@ static const struct elv_fs_entry deadline_attrs[] = {__ATTR_NULL }; +#define RQ_FROM_SEQ_FILE (m) ((struct request_queue *)(m)->private) +#define DD_DATA_FROM_RQ (rq) \ + ((struct deadline_data *)(rq)->elevator->elevator_data) +#ifdef CONFIG_BLK_DEBUG_FS #define DEADLINE_DEBUGFS_DDIR_ATTRS (prio, data_dir, name) \ static void *deadline_##name##_fifo_start(struct seq_file *m, \ loff_t *pos) \ - __acquires(&dd->lock) \ + __acquires(&DD_DATA_FROM_RQ(RQ_FROM_SEQ_FILE(m))->lock) \ { \ struct request_queue *q = m->private; \ struct deadline_data *dd = q->elevator->elevator_data; \
@@ -819,7 +823,7 @@ static void *deadline_##name##_fifo_next(struct seq_file *m, void *v, \ } \ \ static void deadline_##name##_fifo_stop(struct seq_file *m, void *v) \ - __releases(&dd->lock) \ + __releases(&DD_DATA_FROM_RQ(RQ_FROM_SEQ_FILE(m))->lock) \ { \ struct request_queue *q = m->private; \ struct deadline_data *dd = q->elevator->elevator_data; \
@@ -921,7 +925,7 @@ static int dd_owned_by_driver_show(void *data, struct seq_file *m) }static void *deadline_dispatch_start (struct seq_file *m,loff_t *pos) - __acquires(&dd->lock) + __acquires(&DD_DATA_FROM_RQ(RQ_FROM_SEQ_FILE(m))->lock) {struct request_queue *q = m->private;struct deadline_data *dd = q->elevator->elevator_data;
@@ -939,7 +943,7 @@ static void *deadline_dispatch_next(struct seq_file *m, void *v, loff_t *pos) }static void deadline_dispatch_stop (struct seq_file *m,void *v) - __releases(&dd->lock) + __releases(&DD_DATA_FROM_RQ(RQ_FROM_SEQ_FILE(m))->lock) {struct request_queue *q = m->private;struct deadline_data *dd = q->elevator->elevator_data;
Re: [PATCH v7 13/14] block/mq-deadline: Make the lock context annotations compatible with Clang
PATCH v7 14/14 block: Enable lock context analysis
In reply to Bart Van AsscheNow that all block/*.c files have been annotated, enable lock context analysis for all these source files.
--- block/Makefile | 2 ++ 1 file changed, 2 insertions(+)
block/Makefile +2 -0
@@ -3,6 +3,8 @@ # Makefile for the kernel block layer # +CONTEXT_ANALYSIS := y + obj-y := bdev.o fops.o bio.o elevator.o blk-core.o blk-sysfs.o \ blk-flush.o blk-settings.o blk-ioc.o blk-map.o \ blk-merge.o blk-timeout.o blk-lib.o blk-mq.o \
Re: [PATCH v7 14/14] block: Enable lock context analysis
Quoted 11 lines · Bart Van Assche
Recently the following patch series has been merged: [PATCH v5 00/36] Compiler-Based Context- and Locking-Analysis
(https://lore.kernel.org/lkml/[email protected]/). That patch series drops support for verifying lock context annotations with sparse and introduces support for verifying lock context annotations with Clang. The support in Clang for lock context annotation and verification is better than that in sparse. As an example,__cond_acquires()and__guarded_by()are supported by Clang but not by sparse. Hence this patch series that enables lock context analysis for the block layer core.[...]
Applied, thanks!
[01/14] block: Annotate the queue limits functions
commit: 08d912bc44dab63f2637677712d2a0b86922389a
[02/14] block/bdev: Annotate the blk_holder_ops callback functions
commit: 3033c86fa1a8bb31d0a13738fe8c5f9e5bbaf98a
[03/14] block/cgroup: Split blkg_conf_prep()
commit: ea4f575e72df0fa9e4b3f57a6f48c1ae81fac7b4
[04/14] block/cgroup: Split blkg_conf_exit()
commit: c574c3cc368d68fff465e5fc811f874d9235b940
[05/14] block/cgroup: Improve lock context annotations
commit: 9865e416644292124865dfc8a4ffd2b8e6764242
[06/14] block/blk-iocost: Combine two error paths in ioc_qos_write()
commit: 6a7717a2df6c01b2158979f311ddf4cb35b8987f
[07/14] block/cgroup: Inline blkg_conf_{open,close}_bdev_frozen()
commit: 998cda78d4e364f75e576ba715a2533462990aee
[08/14] block/crypto: Annotate the crypto functions
commit: 73bb2480e3eccc6cb2419691c9e60dea9dc6d719
[09/14] block/blk-iocost: Split ioc_rqos_throttle()
commit: 1ff85a387947890938c05cfe22041dfeef3098dd
[10/14] block/blk-iocost: Inline iocg_lock() and iocg_unlock()
commit: a255026594e9b7eea24c12d2bd4acae0c11eea94
[11/14] block/blk-mq-debugfs: Improve lock context annotations
commit: 131f14125a1840d393c3dec8910483e3fc3daf18
[12/14] block/Kyber: Make the lock context annotations compatible with Clang
commit: b4591b91526ef53eedefc124221ec1a060bfbe54
[13/14] block/mq-deadline: Make the lock context annotations compatible with Clang
commit: f10b2de2af28f90c9d1a0774a474e5c4e4d222da
[14/14] block: Enable lock context analysis
commit: 5f0777166e3eaefc02ec0e381658f510f4d068ceBest regards,
Signature · 1 line
Jens Axboe