On 4/23/22 7:07 AM, Jens Axboe wrote: > On 4/23/22 2:06 AM, Pavel Begunkov wrote: >> On 4/22/22 22:42, Jens Axboe wrote: >>> Rather than require ctx->completion_lock for ensuring that we don't >>> clobber the flags, use try_cmpxchg() instead. This removes the need >>> to grab the completion_lock, in preparation for needing to set or >>> clear sq_flags when we don't know the status of this lock. >>> >>> Signed-off-by: Jens Axboe <axboe@xxxxxxxxx> >>> --- >>> fs/io_uring.c | 54 ++++++++++++++++++++++++++++++--------------------- >>> 1 file changed, 32 insertions(+), 22 deletions(-) >>> >>> diff --git a/fs/io_uring.c b/fs/io_uring.c >>> index 626bf840bed2..38e58fe4963d 100644 >>> --- a/fs/io_uring.c >>> +++ b/fs/io_uring.c >>> @@ -1999,6 +1999,34 @@ static void io_cqring_ev_posted_iopoll(struct io_ring_ctx *ctx) >>> io_cqring_wake(ctx); >>> } >>> +static void io_ring_sq_flag_clear(struct io_ring_ctx *ctx, unsigned int flag) >>> +{ >>> + struct io_rings *rings = ctx->rings; >>> + unsigned int oldf, newf; >>> + >>> + do { >>> + oldf = READ_ONCE(rings->sq_flags); >>> + >>> + if (!(oldf & flag)) >>> + break; >>> + newf = oldf & ~flag; >>> + } while (!try_cmpxchg(&rings->sq_flags, &oldf, newf)); >>> +} >>> + >>> +static void io_ring_sq_flag_set(struct io_ring_ctx *ctx, unsigned int flag) >>> +{ >>> + struct io_rings *rings = ctx->rings; >>> + unsigned int oldf, newf; >>> + >>> + do { >>> + oldf = READ_ONCE(rings->sq_flags); >>> + >>> + if (oldf & flag) >>> + break; >>> + newf = oldf | flag; >>> + } while (!try_cmpxchg(&rings->sq_flags, &oldf, newf)); >>> +} >> >> atomic and/or might be a better fit > > That would indeed be great, but the type is fixed. Not sure if all archs > end up with a plain int as the type? Looks like it actually is defined generically, so this could work. -- Jens Axboe