Received: by 2002:ac0:a679:0:0:0:0:0 with SMTP id p54csp126705imp; Wed, 20 Feb 2019 15:50:13 -0800 (PST) X-Google-Smtp-Source: AHgI3IYuRfFEFittM8zU/7lGLjqU313ONDI8KK/1C9K8S1v1Gvuk1N9InevEvrI9Nwmm7PWv4JJ5 X-Received: by 2002:a63:c345:: with SMTP id e5mr31861460pgd.103.1550706613151; Wed, 20 Feb 2019 15:50:13 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1550706613; cv=none; d=google.com; s=arc-20160816; b=DZgBUAc5eMRN71CXvd7Hx4W3f0FckOEtt5+YLF79TxIFt4sJ8qXt3M+E8TQR8lG0+7 KxYL0JGQ+qgm33aCmGXmTVo29MD4shOF5ZuyAtZaRpUy09J5juddjUT+DPNc/P8LzwgH isQRTuCNK7iLX3mi1RNcOyj2GZ6s0F5BzaUe5Zvo0k0Zj71Ga8h8sVEKQ8JhcxqVs+iK CGAD7RZSx9WpzD7FllLCh9OScGLBIrCl3WrHDZd9gunNdGO7g5MfOkgTKQGhdrWAK1Cu SNT2k7ZcWh8/UlfLXaDRKCP4g8D0NEgNU+PSSCYvpFIil6g6laHs8B+zIGIF+evx8w8E IVkA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:dkim-signature:content-transfer-encoding :content-language:in-reply-to:mime-version:user-agent:date :message-id:from:references:cc:to:subject; bh=jHAQ1S277wSPNw74bcLNCENbRjTn4cQT73HLzs0TA7s=; b=o/PjDOS+IfvYaoayXVF6ypY1otWBt/iZfNk3lW5uQD8j9ZmzAXVz0qM3Yv4EIfeOrh VqRhqqFYBlNJTy+W8jbPl9rvp8Bs9lD1VhSkZAmNeNJZAXFMTg48OkSS2kjMh9miYZy3 gqtQh3tMGt6QUPAV2qiZTaFptoqxbxuXwzvTHyZIiStkKFbfa41ZzEs21IQu9glA7Kt2 fLolYWUPz95yz0Da0xrkX6eelnSH6h5eCgC/raUJqycXvc9mUbZa3GeisUdDdscF+XYH zffBc99lgeAWyeuRlDGEzu18vaUHGZ4ayrdAzhzgf+SyEQwRa4NY/i/ptUyPoxb9bqNp jOyg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@nvidia.com header.s=n1 header.b="S8IIpL/H"; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=nvidia.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id f11si5542366plo.96.2019.02.20.15.49.57; Wed, 20 Feb 2019 15:50:13 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@nvidia.com header.s=n1 header.b="S8IIpL/H"; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=nvidia.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726643AbfBTXsG (ORCPT + 99 others); Wed, 20 Feb 2019 18:48:06 -0500 Received: from hqemgate14.nvidia.com ([216.228.121.143]:11837 "EHLO hqemgate14.nvidia.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725989AbfBTXsF (ORCPT ); Wed, 20 Feb 2019 18:48:05 -0500 Received: from hqpgpgate102.nvidia.com (Not Verified[216.228.121.13]) by hqemgate14.nvidia.com (using TLS: TLSv1.2, DES-CBC3-SHA) id ; Wed, 20 Feb 2019 15:48:13 -0800 Received: from hqmail.nvidia.com ([172.20.161.6]) by hqpgpgate102.nvidia.com (PGP Universal service); Wed, 20 Feb 2019 15:48:04 -0800 X-PGP-Universal: processed; by hqpgpgate102.nvidia.com on Wed, 20 Feb 2019 15:48:04 -0800 Received: from [10.2.169.124] (10.124.1.5) by HQMAIL101.nvidia.com (172.20.187.10) with Microsoft SMTP Server (TLS) id 15.0.1395.4; Wed, 20 Feb 2019 23:48:01 +0000 Subject: Re: [PATCH 01/10] mm/hmm: use reference counting for HMM struct To: , CC: , Ralph Campbell , Andrew Morton References: <20190129165428.3931-1-jglisse@redhat.com> <20190129165428.3931-2-jglisse@redhat.com> X-Nvconfidentiality: public From: John Hubbard Message-ID: <1373673d-721e-a7a2-166f-244c16f236a3@nvidia.com> Date: Wed, 20 Feb 2019 15:47:50 -0800 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.5.0 MIME-Version: 1.0 In-Reply-To: <20190129165428.3931-2-jglisse@redhat.com> X-Originating-IP: [10.124.1.5] X-ClientProxiedBy: HQMAIL108.nvidia.com (172.18.146.13) To HQMAIL101.nvidia.com (172.20.187.10) Content-Type: text/plain; charset="utf-8"; format=flowed Content-Language: en-US Content-Transfer-Encoding: quoted-printable DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nvidia.com; s=n1; t=1550706493; bh=jHAQ1S277wSPNw74bcLNCENbRjTn4cQT73HLzs0TA7s=; h=X-PGP-Universal:Subject:To:CC:References:X-Nvconfidentiality:From: Message-ID:Date:User-Agent:MIME-Version:In-Reply-To: X-Originating-IP:X-ClientProxiedBy:Content-Type:Content-Language: Content-Transfer-Encoding; b=S8IIpL/Hp0VGxgHTwAkM2gbYHBrtTCjE3Yfp1s+vcLE6/tZcpI4EmwwOuuyTTwKJC X60eczHn4cvEZrq8SFZtL62Qf6Fb3tKQC1K6avJSmN6HP6qlMNL6f8zQXE4+2BIWsB uWbXwuwj/JiAaFZsWNABDJRNj4oNd/+RcIkjGJUNC6CnFzM4q8JRZrFTfk8F2bCmDT SfXDR85wxL9uszLKCRw+Y/ToofuIDv06tBlx2gfsg11TC390l157HJj4q8UMQbtH0k cUyKraxBfClV88yj6mvGTfqnNMMlS8i09pReH9DxmH+8HD/2qEeBqGd2PX2dPBUWeG LQasmnrnYNX5A== Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 1/29/19 8:54 AM, jglisse@redhat.com wrote: > From: J=C3=A9r=C3=B4me Glisse >=20 > Every time i read the code to check that the HMM structure does not > vanish before it should thanks to the many lock protecting its removal > i get a headache. Switch to reference counting instead it is much > easier to follow and harder to break. This also remove some code that > is no longer needed with refcounting. Hi Jerome, That is an excellent idea. Some review comments below: [snip] > static int hmm_invalidate_range_start(struct mmu_notifier *mn, > const struct mmu_notifier_range *range) > { > struct hmm_update update; > - struct hmm *hmm =3D range->mm->hmm; > + struct hmm *hmm =3D hmm_get(range->mm); > + int ret; > =20 > VM_BUG_ON(!hmm); > =20 > + /* Check if hmm_mm_destroy() was call. */ > + if (hmm->mm =3D=3D NULL) > + return 0; Let's delete that NULL check. It can't provide true protection. If there is a way for that to race, we need to take another look at refcounting. Is there a need for mmgrab()/mmdrop(), to keep the mm around while HMM is using it? > + > update.start =3D range->start; > update.end =3D range->end; > update.event =3D HMM_UPDATE_INVALIDATE; > update.blockable =3D range->blockable; > - return hmm_invalidate_range(hmm, true, &update); > + ret =3D hmm_invalidate_range(hmm, true, &update); > + hmm_put(hmm); > + return ret; > } > =20 > static void hmm_invalidate_range_end(struct mmu_notifier *mn, > const struct mmu_notifier_range *range) > { > struct hmm_update update; > - struct hmm *hmm =3D range->mm->hmm; > + struct hmm *hmm =3D hmm_get(range->mm); > =20 > VM_BUG_ON(!hmm); > =20 > + /* Check if hmm_mm_destroy() was call. */ > + if (hmm->mm =3D=3D NULL) > + return; > + Another one to delete, same reasoning as above. [snip] > @@ -717,14 +746,18 @@ int hmm_vma_get_pfns(struct hmm_range *range) > hmm =3D hmm_register(vma->vm_mm); > if (!hmm) > return -ENOMEM; > - /* Caller must have registered a mirror, via hmm_mirror_register() ! */ > - if (!hmm->mmu_notifier.ops) > + > + /* Check if hmm_mm_destroy() was call. */ > + if (hmm->mm =3D=3D NULL) { > + hmm_put(hmm); > return -EINVAL; > + } > =20 Another hmm->mm NULL check to remove. [snip] > @@ -802,25 +842,27 @@ EXPORT_SYMBOL(hmm_vma_get_pfns); > */ > bool hmm_vma_range_done(struct hmm_range *range) > { > - unsigned long npages =3D (range->end - range->start) >> PAGE_SHIFT; > - struct hmm *hmm; > + bool ret =3D false; > =20 > - if (range->end <=3D range->start) { > + /* Sanity check this really should not happen. */ > + if (range->hmm =3D=3D NULL || range->end <=3D range->start) { > BUG(); > return false; > } > =20 > - hmm =3D hmm_register(range->vma->vm_mm); > - if (!hmm) { > - memset(range->pfns, 0, sizeof(*range->pfns) * npages); > - return false; > - } > - > - spin_lock(&hmm->lock); > + spin_lock(&range->hmm->lock); > list_del_rcu(&range->list); > - spin_unlock(&hmm->lock); > + ret =3D range->valid; > + spin_unlock(&range->hmm->lock); > =20 > - return range->valid; > + /* Is the mm still alive ? */ > + if (range->hmm->mm =3D=3D NULL) > + ret =3D false; And another one here. > + > + /* Drop reference taken by hmm_vma_fault() or hmm_vma_get_pfns() */ > + hmm_put(range->hmm); > + range->hmm =3D NULL; > + return ret; > } > EXPORT_SYMBOL(hmm_vma_range_done); > =20 > @@ -880,6 +922,8 @@ int hmm_vma_fault(struct hmm_range *range, bool block= ) > struct hmm *hmm; > int ret; > =20 > + range->hmm =3D NULL; > + > /* Sanity check, this really should not happen ! */ > if (range->start < vma->vm_start || range->start >=3D vma->vm_end) > return -EINVAL; > @@ -891,14 +935,18 @@ int hmm_vma_fault(struct hmm_range *range, bool blo= ck) > hmm_pfns_clear(range, range->pfns, range->start, range->end); > return -ENOMEM; > } > - /* Caller must have registered a mirror using hmm_mirror_register() */ > - if (!hmm->mmu_notifier.ops) > + > + /* Check if hmm_mm_destroy() was call. */ > + if (hmm->mm =3D=3D NULL) { > + hmm_put(hmm); > return -EINVAL; > + } And here. > =20 > /* FIXME support hugetlb fs */ > if (is_vm_hugetlb_page(vma) || (vma->vm_flags & VM_SPECIAL) || > vma_is_dax(vma)) { > hmm_pfns_special(range); > + hmm_put(hmm); > return -EINVAL; > } > =20 > @@ -910,6 +958,7 @@ int hmm_vma_fault(struct hmm_range *range, bool block= ) > * operations such has atomic access would not work. > */ > hmm_pfns_clear(range, range->pfns, range->start, range->end); > + hmm_put(hmm); > return -EPERM; > } > =20 > @@ -945,7 +994,16 @@ int hmm_vma_fault(struct hmm_range *range, bool bloc= k) > hmm_pfns_clear(range, &range->pfns[i], hmm_vma_walk.last, > range->end); > hmm_vma_range_done(range); > + hmm_put(hmm); > + } else { > + /* > + * Transfer hmm reference to the range struct it will be drop > + * inside the hmm_vma_range_done() function (which _must_ be > + * call if this function return 0). > + */ > + range->hmm =3D hmm; Is that thread-safe? Is there anything preventing two or more threads from changing range->hmm at the same time? thanks, --=20 John Hubbard NVIDIA