Received: by 2002:a05:6a10:9848:0:0:0:0 with SMTP id x8csp241727pxf; Wed, 10 Mar 2021 05:28:30 -0800 (PST) X-Google-Smtp-Source: ABdhPJx3lc2iC+kXNZerWr5qJ9YGALA1h6JQ/NRvB3Ygqr3/ihu4Ii5XrCx2cAkEoAWJ18MwXwGE X-Received: by 2002:a17:906:400b:: with SMTP id v11mr3698308ejj.194.1615382910091; Wed, 10 Mar 2021 05:28:30 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1615382910; cv=none; d=google.com; s=arc-20160816; b=ivVUogn+G5nWqQeELEWvJ+dpEf91XuiB2LHrm3nXDr7OYGertYftzdvbiqWTNRYM6U f7In/ZlE22yrDfsZsebnPGE40YkduKJp15cpWPYNDzxiyJ3UD92vs2pQKhxLrKDHQZFk 5tB9KPckPFQNWLZ5HhmMG6bqnX1hBmmvARJ7EWw43kURIFZ7k4E72l5/r09TF52ajD7E 0ygrn+wrQ4MOKUmnnsIGhcXVJv+6SxZk0C2oIphQHPKjgeUHL7rEXQLmJFLQ2/wEssov 0cjRJ37axjymw7CwG0AXsIQA/epJdvVUzpbmCGnzfHCrZk+BS1oD7PIysALk3L8RAJDY rGIw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=cT1JpiE7KXuTJYaYCASqwTS5ZeOxJEp2bNe4FCXY8U4=; b=kT3IU/AjtAeu0H4VlHPbVS8mQzKxUFtDh27VV1o7yqu/qaGT8jhyNa/M7JlySARxUI dSsJWoIs9k+PCVyfn+PHM2N75NTc8SvYY3QWcP6graQtvYxfT10W6Du0xRDTx5CtnJuz RmTGrxq5qwepXFKsXTb17skCOuctUdw06vOZuOQIhfChsdDIb7zUMteI+w5Pz2S/AKeO IBUI2RGOqY1P01k/cDJRpqw7KyHXPZMw6pRmaJLztriu6BKTx9jd08djpE7pDjpZjGsQ kGjc20ehp3fNUugAatembTbGaxCEi6XMD/ePfPYTIWWOzJa0jc7/XoD/qfyrCG+IGqN1 FGPA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=BrFluFGy; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id b24si11177686edr.415.2021.03.10.05.28.05; Wed, 10 Mar 2021 05:28:30 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=BrFluFGy; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linuxfoundation.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233060AbhCJNYu (ORCPT + 99 others); Wed, 10 Mar 2021 08:24:50 -0500 Received: from mail.kernel.org ([198.145.29.99]:45420 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232775AbhCJNYK (ORCPT ); Wed, 10 Mar 2021 08:24:10 -0500 Received: by mail.kernel.org (Postfix) with ESMTPSA id 40DE764FD8; Wed, 10 Mar 2021 13:24:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1615382650; bh=KHkhqCTHzoARLpsg7NujAfuMlD/XneCIow5T3aalXrY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=BrFluFGyVjzEREjtDjLOGwXWnGUQjxaz26XMYf9pNRx9UwAaIQnlB/CpTV/xzvhRe fIL3y+bNV0xkzkPn5Pj+fwQI4rNVuIWVV0Hxh1qhqD115SQJpkj/wOspQOVPD4/+7m YQa8Ev4JnKAVf0+QBXbL6m2ZIN/br6TlF+jhHy+E= From: gregkh@linuxfoundation.org To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Greg Kroah-Hartman , Jens Axboe , Pavel Begunkov Subject: [PATCH 5.11 09/36] io_uring/io-wq: return 2-step work swap scheme Date: Wed, 10 Mar 2021 14:23:22 +0100 Message-Id: <20210310132320.812008964@linuxfoundation.org> X-Mailer: git-send-email 2.30.2 In-Reply-To: <20210310132320.510840709@linuxfoundation.org> References: <20210310132320.510840709@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Greg Kroah-Hartman From: Pavel Begunkov commit 5280f7e530f71ba85baf90169393196976ad0e52 upstream Saving one lock/unlock for io-wq is not super important, but adds some ugliness in the code. More important, atomic decs not turning it to zero for some archs won't give the right ordering/barriers so the io_steal_work() may pretty easily get subtly and completely broken. Return back 2-step io-wq work exchange and clean it up. Signed-off-by: Pavel Begunkov Signed-off-by: Jens Axboe Signed-off-by: Greg Kroah-Hartman --- fs/io-wq.c | 16 ++++++---------- fs/io-wq.h | 4 ++-- fs/io_uring.c | 26 ++++---------------------- 3 files changed, 12 insertions(+), 34 deletions(-) --- a/fs/io-wq.c +++ b/fs/io-wq.c @@ -555,23 +555,21 @@ get_next: /* handle a whole dependent link */ do { - struct io_wq_work *old_work, *next_hashed, *linked; + struct io_wq_work *next_hashed, *linked; unsigned int hash = io_get_work_hash(work); next_hashed = wq_next_work(work); io_impersonate_work(worker, work); + wq->do_work(work); + io_assign_current_work(worker, NULL); - old_work = work; - linked = wq->do_work(work); - + linked = wq->free_work(work); work = next_hashed; if (!work && linked && !io_wq_is_hashed(linked)) { work = linked; linked = NULL; } io_assign_current_work(worker, work); - wq->free_work(old_work); - if (linked) io_wqe_enqueue(wqe, linked); @@ -850,11 +848,9 @@ static void io_run_cancel(struct io_wq_w struct io_wq *wq = wqe->wq; do { - struct io_wq_work *old_work = work; - work->flags |= IO_WQ_WORK_CANCEL; - work = wq->do_work(work); - wq->free_work(old_work); + wq->do_work(work); + work = wq->free_work(work); } while (work); } --- a/fs/io-wq.h +++ b/fs/io-wq.h @@ -106,8 +106,8 @@ static inline struct io_wq_work *wq_next return container_of(work->list.next, struct io_wq_work, list); } -typedef void (free_work_fn)(struct io_wq_work *); -typedef struct io_wq_work *(io_wq_work_fn)(struct io_wq_work *); +typedef struct io_wq_work *(free_work_fn)(struct io_wq_work *); +typedef void (io_wq_work_fn)(struct io_wq_work *); struct io_wq_data { struct user_struct *user; --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -2365,22 +2365,6 @@ static inline void io_put_req_deferred(s io_free_req_deferred(req); } -static struct io_wq_work *io_steal_work(struct io_kiocb *req) -{ - struct io_kiocb *nxt; - - /* - * A ref is owned by io-wq in which context we're. So, if that's the - * last one, it's safe to steal next work. False negatives are Ok, - * it just will be re-punted async in io_put_work() - */ - if (refcount_read(&req->refs) != 1) - return NULL; - - nxt = io_req_find_next(req); - return nxt ? &nxt->work : NULL; -} - static void io_double_put_req(struct io_kiocb *req) { /* drop both submit and complete references */ @@ -6378,7 +6362,7 @@ static int io_issue_sqe(struct io_kiocb return 0; } -static struct io_wq_work *io_wq_submit_work(struct io_wq_work *work) +static void io_wq_submit_work(struct io_wq_work *work) { struct io_kiocb *req = container_of(work, struct io_kiocb, work); struct io_kiocb *timeout; @@ -6429,8 +6413,6 @@ static struct io_wq_work *io_wq_submit_w if (lock_ctx) mutex_unlock(&lock_ctx->uring_lock); } - - return io_steal_work(req); } static inline struct file *io_file_from_index(struct io_ring_ctx *ctx, @@ -8062,12 +8044,12 @@ static int io_sqe_files_update(struct io return __io_sqe_files_update(ctx, &up, nr_args); } -static void io_free_work(struct io_wq_work *work) +static struct io_wq_work *io_free_work(struct io_wq_work *work) { struct io_kiocb *req = container_of(work, struct io_kiocb, work); - /* Consider that io_steal_work() relies on this ref */ - io_put_req(req); + req = io_put_req_find_next(req); + return req ? &req->work : NULL; } static int io_init_wq_offload(struct io_ring_ctx *ctx,