Received: by 2002:a05:6a10:1287:0:0:0:0 with SMTP id d7csp633478pxv; Thu, 15 Jul 2021 12:03:14 -0700 (PDT) X-Google-Smtp-Source: ABdhPJwFnc9k+51t27rZ2pdiAPQ3ykR7Y2pAyrOutNcdRiGU1SUHYmsaVFgUu9Y1iGjZ6oTJ0T6r X-Received: by 2002:a5d:91d8:: with SMTP id k24mr4326697ior.84.1626375794076; Thu, 15 Jul 2021 12:03:14 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1626375794; cv=none; d=google.com; s=arc-20160816; b=SaukVK9igAz3MJMfdCWNzE/QfHvLSRwUUk0BA/2Idw97YdfbTVQMMIIr8AhN1kPIB6 rNRmndnt9OEO2NfG/qW7IYiYFlfOKZIK3EJ9NcqX/21v7eEJT5FZrsKahb0EAFZEkFJ8 JUpCEmDDVbIR4h3xxnUYsgDvKG9j+QpdJVEEDW8Zw2iHPUFqe0h362ATiNApeeGldBpG h7aBb2VdvmPvPIuG1I5ps9no6QwzwGn5764HswbbTaEpYn52yHX+HB80zVVdARKl/ePk fvBgU8mUq9YsQViI1dDVN8g65L1rkvgLUx2vwErNzxONwtSa3pHuGAiuIaPK1NwGH49V QCUA== 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=w9wBq4TPa6ANDMdIP5gcf7lIjECfbn+/zfKtSq5kO8Y=; b=Otx0jmg9CLbuZUZ8Do92WZ9PGlUSC0z4vT/OSn+y6DDK7L4+sR8Hkgsnx6gMOdOQOq uacKq5c8gkWlJfqEhCG09IEHiuIRAxwg1LtskuwQmABHbsab35rox+FGbtOuv/opBKdo zGpNmm10wCtbbOEoHK4gTAD8zzqLnzBUOglWfcF8wRvd0MdtCYWdi/M5dhWnnNwvPRvB aomijjQJjf5K/33Agxzej9nq2GxfdUR0NcD5mBjPPiStQsNWjx+p4rjKgbUEjdRYCAqr /Oyw+YDZrtr9eQZjsbRXeFzQzJ3j503GMAWiIdr9dmprcXuHYJyEd1ADNyGTW8qyIaqU ECaA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linuxfoundation.org header.s=korg header.b=V6JcmSuf; 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 d20si7663400ioo.61.2021.07.15.12.03.01; Thu, 15 Jul 2021 12:03:14 -0700 (PDT) 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=V6JcmSuf; 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 S243416AbhGOTEX (ORCPT + 99 others); Thu, 15 Jul 2021 15:04:23 -0400 Received: from mail.kernel.org ([198.145.29.99]:57842 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240599AbhGOSyA (ORCPT ); Thu, 15 Jul 2021 14:54:00 -0400 Received: by mail.kernel.org (Postfix) with ESMTPSA id BDCB9613D0; Thu, 15 Jul 2021 18:51:06 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=linuxfoundation.org; s=korg; t=1626375067; bh=PolS+7aZnFZs1pDZxZ9Fgg0SpLVGAqOvR8aCwenTItE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=V6JcmSufoRXvTOGmMSPsWrPuwa2VE+XtEACvx/JAs2BGOyj1RP8mfcZDMQ7f0bOeX AaM5zsEijjJvUU0WsLooN8CW52mVCg4BklRtXWZLpCHiSbnLLbbdEss9BIteYVcN4C pvXUVfrHQMo5dQSvhLnFJok31EmbtxyuKadSvMRk= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Greg Kroah-Hartman , Matthew Wilcox , yangerkun , Hulk Robot , Jens Axboe , Hanjun Guo Subject: [PATCH 5.10 143/215] io_uring: convert io_buffer_idr to XArray Date: Thu, 15 Jul 2021 20:38:35 +0200 Message-Id: <20210715182624.875109621@linuxfoundation.org> X-Mailer: git-send-email 2.32.0 In-Reply-To: <20210715182558.381078833@linuxfoundation.org> References: <20210715182558.381078833@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: Jens Axboe commit 9e15c3a0ced5a61f320b989072c24983cb1620c1 upstream. Like we did for the personality idr, convert the IO buffer idr to use XArray. This avoids a use-after-free on removal of entries, since idr doesn't like doing so from inside an iterator, and it nicely reduces the amount of code we need to support this feature. Fixes: 5a2e745d4d43 ("io_uring: buffer registration infrastructure") Cc: stable@vger.kernel.org Cc: Matthew Wilcox Cc: yangerkun Reported-by: Hulk Robot Signed-off-by: Jens Axboe Signed-off-by: Hanjun Guo Signed-off-by: Greg Kroah-Hartman --- fs/io_uring.c | 43 +++++++++++++++---------------------------- 1 file changed, 15 insertions(+), 28 deletions(-) --- a/fs/io_uring.c +++ b/fs/io_uring.c @@ -344,7 +344,7 @@ struct io_ring_ctx { struct socket *ring_sock; #endif - struct idr io_buffer_idr; + struct xarray io_buffers; struct xarray personalities; u32 pers_next; @@ -1212,7 +1212,7 @@ static struct io_ring_ctx *io_ring_ctx_a INIT_LIST_HEAD(&ctx->cq_overflow_list); init_completion(&ctx->ref_comp); init_completion(&ctx->sq_thread_comp); - idr_init(&ctx->io_buffer_idr); + xa_init_flags(&ctx->io_buffers, XA_FLAGS_ALLOC1); xa_init_flags(&ctx->personalities, XA_FLAGS_ALLOC1); mutex_init(&ctx->uring_lock); init_waitqueue_head(&ctx->wait); @@ -2990,7 +2990,7 @@ static struct io_buffer *io_buffer_selec lockdep_assert_held(&req->ctx->uring_lock); - head = idr_find(&req->ctx->io_buffer_idr, bgid); + head = xa_load(&req->ctx->io_buffers, bgid); if (head) { if (!list_empty(&head->list)) { kbuf = list_last_entry(&head->list, struct io_buffer, @@ -2998,7 +2998,7 @@ static struct io_buffer *io_buffer_selec list_del(&kbuf->list); } else { kbuf = head; - idr_remove(&req->ctx->io_buffer_idr, bgid); + xa_erase(&req->ctx->io_buffers, bgid); } if (*len > kbuf->len) *len = kbuf->len; @@ -3960,7 +3960,7 @@ static int __io_remove_buffers(struct io } i++; kfree(buf); - idr_remove(&ctx->io_buffer_idr, bgid); + xa_erase(&ctx->io_buffers, bgid); return i; } @@ -3978,7 +3978,7 @@ static int io_remove_buffers(struct io_k lockdep_assert_held(&ctx->uring_lock); ret = -ENOENT; - head = idr_find(&ctx->io_buffer_idr, p->bgid); + head = xa_load(&ctx->io_buffers, p->bgid); if (head) ret = __io_remove_buffers(ctx, head, p->bgid, p->nbufs); if (ret < 0) @@ -4069,21 +4069,14 @@ static int io_provide_buffers(struct io_ lockdep_assert_held(&ctx->uring_lock); - list = head = idr_find(&ctx->io_buffer_idr, p->bgid); + list = head = xa_load(&ctx->io_buffers, p->bgid); ret = io_add_buffers(p, &head); - if (ret < 0) - goto out; - - if (!list) { - ret = idr_alloc(&ctx->io_buffer_idr, head, p->bgid, p->bgid + 1, - GFP_KERNEL); - if (ret < 0) { + if (ret >= 0 && !list) { + ret = xa_insert(&ctx->io_buffers, p->bgid, head, GFP_KERNEL); + if (ret < 0) __io_remove_buffers(ctx, head, p->bgid, -1U); - goto out; - } } -out: if (ret < 0) req_set_fail_links(req); @@ -8411,19 +8404,13 @@ static int io_eventfd_unregister(struct return -ENXIO; } -static int __io_destroy_buffers(int id, void *p, void *data) -{ - struct io_ring_ctx *ctx = data; - struct io_buffer *buf = p; - - __io_remove_buffers(ctx, buf, id, -1U); - return 0; -} - static void io_destroy_buffers(struct io_ring_ctx *ctx) { - idr_for_each(&ctx->io_buffer_idr, __io_destroy_buffers, ctx); - idr_destroy(&ctx->io_buffer_idr); + struct io_buffer *buf; + unsigned long index; + + xa_for_each(&ctx->io_buffers, index, buf) + __io_remove_buffers(ctx, buf, index, -1U); } static void io_ring_ctx_free(struct io_ring_ctx *ctx)