From patchwork Wed Jul 11 02:55:17 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Gunthorpe X-Patchwork-Id: 10518699 X-Patchwork-Delegate: jgg@ziepe.ca Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 74A8D6032C for ; Wed, 11 Jul 2018 02:55:37 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 5B27428BAC for ; Wed, 11 Jul 2018 02:55:37 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 4F1BE28CC7; Wed, 11 Jul 2018 02:55:37 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, MAILING_LIST_MULTI, RCVD_IN_DNSWL_HI, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id B66A328BAC for ; Wed, 11 Jul 2018 02:55:36 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1732425AbeGKC5j (ORCPT ); Tue, 10 Jul 2018 22:57:39 -0400 Received: from mail-wm0-f65.google.com ([74.125.82.65]:52767 "EHLO mail-wm0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1732316AbeGKC5j (ORCPT ); Tue, 10 Jul 2018 22:57:39 -0400 Received: by mail-wm0-f65.google.com with SMTP id w16-v6so872729wmc.2 for ; Tue, 10 Jul 2018 19:55:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ziepe.ca; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=+5xCVdCuMXcqi/cKjcDjvA2Axt7DuYWwB+QPouSUTvA=; b=Q6r+ELmekiMYChkW0Ht8WQRkVJ+P6u322hsgkHbrvQVFyk/9nDic88dQxBGNsgU1Jn 0rWTiou5dNiHOA2VonCjf341b3Yd4PH6yn/KP6OhOAaqc4v3kzsC4Vat2LKeOAk55czp hc/W5FHO0/Z1Y9VhKh47+lwTpD9jIy1gB3YlKy0Ao/ZrcA5t61EASmZbtIlAOYyaGVOm n13AkQek27n3ifL3mlK7m9qHbunH4gsGIh5IN7Ypwb02s5TJmQ1dxhaI7W4kuQ5HaubY drfxoW1eSyBKkKQ/H9/9yTnpg0iadu3StdyVmdhV/JaNOEBZffgg2AH33LFIOJ71kJ2B 7LYw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=+5xCVdCuMXcqi/cKjcDjvA2Axt7DuYWwB+QPouSUTvA=; b=d0wyfAu5myt9UUzLVkkkt+ZHgAyEK7ulXcjTvQ7Sh5GFH3Qsrz+zrDwZwECGgPKQKE O8K2I4kKrJT19uzSxPx9KwBtXWFsddT3LJAFD8jyIpQlzSjQw2Lf4HOP4Wd7YBqn/se6 wf7vRe+e/wnGrL7M3UQR2rqcQ3DMJg1NXS4Muus5V2kAifKRIiUQ8qzQ15+Md24OCckI n+Nz9YiJotvUyt4qgPUGjwXaFKTRzWz2NRnqIyu3ZjfrHGWNvnJALiV1dDjAYxzG3xfv j1QHXj7E/wfI10AacKXNpziwZ9djQjSYvyDSMo79AFFvwHgNDKgXW9bPZW2gUFj5DW5G HZaA== X-Gm-Message-State: APt69E06dcmywSwKeoSWQ5EkNO11nLGqBgie1J/olEALglBv6O4oZWFF eyu0duC93+kwtZS1v7dTevJyopNk4Rc= X-Google-Smtp-Source: AAOMgpeTHEQh/6YNGOnc4PEBZGFGS1UPkXiEUaSJ6+cM/aDdPcKJSey4SDcwoGXZKoL8rcdBM3erug== X-Received: by 2002:a1c:9350:: with SMTP id v77-v6mr16930926wmd.146.1531277733449; Tue, 10 Jul 2018 19:55:33 -0700 (PDT) Received: from ziepe.ca (S010614cc2056d97f.ed.shawcable.net. [174.3.196.123]) by smtp.gmail.com with ESMTPSA id 35-v6sm997911wrh.52.2018.07.10.19.55.31 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 10 Jul 2018 19:55:32 -0700 (PDT) Received: from jgg by mlx.ziepe.ca with local (Exim 4.86_2) (envelope-from ) id 1fd5Hs-0007r2-9f; Tue, 10 Jul 2018 20:55:28 -0600 From: Jason Gunthorpe To: linux-rdma@vger.kernel.org, Leon Romanovsky , "Guy Levi(SW)" , Yishai Hadas , "Ruhl, Michael J" Cc: Jason Gunthorpe Subject: [PATCH 05/11] IB/uverbs: Clarify and revise uverbs_close_fd Date: Tue, 10 Jul 2018 20:55:17 -0600 Message-Id: <20180711025523.30102-6-jgg@ziepe.ca> X-Mailer: git-send-email 2.18.0 In-Reply-To: <20180711025523.30102-1-jgg@ziepe.ca> References: <20180711025523.30102-1-jgg@ziepe.ca> Sender: linux-rdma-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-rdma@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: Jason Gunthorpe The locking requirements here have changed slightly now that we can rely on the ib_uverbs_file always existing and containing all the necessary locking infrastructure. That means we can get rid of the cleanup_mutex usage (this was protecting the check on !uboj->context). Otherwise, follow the same pattern that IDR uses for destroy, acquire exclusive write access, then call destroy and the undo the 'lookup'. Signed-off-by: Jason Gunthorpe --- drivers/infiniband/core/rdma_core.c | 41 ++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 13 deletions(-) diff --git a/drivers/infiniband/core/rdma_core.c b/drivers/infiniband/core/rdma_core.c index 80e1e3cb211071..a55646cbf9b142 100644 --- a/drivers/infiniband/core/rdma_core.c +++ b/drivers/infiniband/core/rdma_core.c @@ -650,33 +650,48 @@ EXPORT_SYMBOL(uverbs_idr_class); static void _uverbs_close_fd(struct ib_uobject *uobj) { - struct ib_uverbs_file *ufile = uobj->ufile; int ret; - mutex_lock(&ufile->cleanup_mutex); + /* + * uobject was already cleaned up, remove_commit_fd_uobject + * sets this + */ + if (!uobj->context) + return; - /* uobject was either already cleaned up or is cleaned up right now anyway */ - if (!uobj->context || - !down_read_trylock(&ufile->cleanup_rwsem)) - goto unlock; + /* + * lookup_get_fd_uobject holds the kref on the struct file any time a + * FD uobj is locked, which prevents this release method from being + * invoked. Meaning we can always get the write lock here, or we have + * a kernel bug. If so dangle the pointers and bail. + */ + ret = uverbs_try_lock_object(uobj, true); + if (WARN(ret, "uverbs_close_fd() racing with lookup_get_fd_uobject()")) + return; ret = _rdma_remove_commit_uobject(uobj, RDMA_REMOVE_CLOSE); - up_read(&ufile->cleanup_rwsem); if (ret) - pr_warn("uverbs: unable to clean up uobject file in uverbs_close_fd.\n"); -unlock: - mutex_unlock(&ufile->cleanup_mutex); + pr_warn("Unable to clean up uobject file in %s\n", __func__); + + atomic_set(&uobj->usecnt, 0); } void uverbs_close_fd(struct file *f) { struct ib_uobject *uobj = f->private_data; - struct kref *uverbs_file_ref = &uobj->ufile->ref; + struct ib_uverbs_file *ufile = uobj->ufile; + + if (down_read_trylock(&ufile->cleanup_rwsem)) { + _uverbs_close_fd(uobj); + up_read(&ufile->cleanup_rwsem); + } + + uobj->object = NULL; + /* Matches the get in alloc_begin_fd_uobject */ + kref_put(&ufile->ref, ib_uverbs_release_file); - _uverbs_close_fd(uobj); /* Pairs with filp->private_data in alloc_begin_fd_uobject */ uverbs_uobject_put(uobj); - kref_put(uverbs_file_ref, ib_uverbs_release_file); } static int __uverbs_cleanup_ufile(struct ib_uverbs_file *ufile,