From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 45947C04A6A for ; Thu, 3 Aug 2023 08:32:52 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id D143A28021A; Thu, 3 Aug 2023 04:32:51 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id CC5382801EB; Thu, 3 Aug 2023 04:32:51 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id B642C28021A; Thu, 3 Aug 2023 04:32:51 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0013.hostedemail.com [216.40.44.13]) by kanga.kvack.org (Postfix) with ESMTP id A47D32801EB for ; Thu, 3 Aug 2023 04:32:51 -0400 (EDT) Received: from smtpin27.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay07.hostedemail.com (Postfix) with ESMTP id 65643160740 for ; Thu, 3 Aug 2023 08:32:51 +0000 (UTC) X-FDA: 81082127742.27.2966A16 Received: from mail-ej1-f44.google.com (mail-ej1-f44.google.com [209.85.218.44]) by imf06.hostedemail.com (Postfix) with ESMTP id 07779180005 for ; Thu, 3 Aug 2023 08:32:48 +0000 (UTC) Authentication-Results: imf06.hostedemail.com; dkim=pass header.d=ffwll.ch header.s=google header.b=OinXHeMd; dmarc=none; spf=none (imf06.hostedemail.com: domain of daniel@ffwll.ch has no SPF policy when checking 209.85.218.44) smtp.mailfrom=daniel@ffwll.ch ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1691051569; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=pAuYs/QLB03KHLO4kdZKV+yQgSaaMVS+owEl2g8UVew=; b=F5yOhDNll6RIhEB9/TtvH55Cy1OvKlzxOGk1CO2UATvpvvm6Wjzsg3LGfVutS7pBh2fLqo 3z3Wuon2Sc2/T7W5aatkRToJEpCmhIyZBAHERRhNHvFh/IWP1DVBq+GdLfUxHU8zL4LbbZ qBePN09La4rCnoX9E78DM2xf/UUYEUw= ARC-Authentication-Results: i=1; imf06.hostedemail.com; dkim=pass header.d=ffwll.ch header.s=google header.b=OinXHeMd; dmarc=none; spf=none (imf06.hostedemail.com: domain of daniel@ffwll.ch has no SPF policy when checking 209.85.218.44) smtp.mailfrom=daniel@ffwll.ch ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1691051569; a=rsa-sha256; cv=none; b=Y01BXCBbCMZhBp7GxZaboju9dwPiS9P3EQmoyeYShbYQcCtPA+o7VTg3uV4ew7ZrnzJhAH fSGxz7s86is3bdwnGJRmkDARHAd71gYWk7xA9U2yA8sGwR8MXc4A22uK4FS6piYFkcmDD3 k4UtkULK3Oq4wNBJDeebELYVOLd6qkU= Received: by mail-ej1-f44.google.com with SMTP id a640c23a62f3a-99bcf3c8524so19656166b.0 for ; Thu, 03 Aug 2023 01:32:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ffwll.ch; s=google; t=1691051567; x=1691656367; h=in-reply-to:content-disposition:mime-version:references :mail-followup-to:message-id:subject:cc:to:from:date:from:to:cc :subject:date:message-id:reply-to; bh=pAuYs/QLB03KHLO4kdZKV+yQgSaaMVS+owEl2g8UVew=; b=OinXHeMd1J3TBhjnEJAorVBhcxGC5qSG+hUjMeuzVE2EC54SfmvGt85V16q8/E8TSw C8cd8MuV27mKRQyCSQhqjtXbu32WTMV4vfCmNe+LVfa8/Lo960ImVgJEZdZw6FZD8tWe gCqCMOQqzxfv1l/nuNvquFsqVViEZfSMEKRzo= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1691051567; x=1691656367; h=in-reply-to:content-disposition:mime-version:references :mail-followup-to:message-id:subject:cc:to:from:date :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=pAuYs/QLB03KHLO4kdZKV+yQgSaaMVS+owEl2g8UVew=; b=Dm/vokEpI4W302DeG0necNV+n6wLAqYO2e2hibsg9ou/6V/3VU1YQeUXfYnwz2DuMM zr4ofecBlJHpJe+sqEBaKfeeDz5gp2nqkau9Vn3ZbhKk6el7yxLHMGuBiM6eK7YokFHf bnpahXZG5H5VQrjdfPHf7noW+rAeCYKIIKdHGRRq5tcuL3Ca0fLCOXep8gd/jt+E3Kuz DlVUM7+y+fd1wGercT2xzNHMYW22soM7ljyC/vPfJrx+VJTWpS5nBbn4KJfWSSVeRd+q 4OxLRRg4/XjasCn8I2fomklvNMhmf0Vr741d8hGi97oY5sRBPi4GBZ+BzD/x51hsQhPZ 8wvw== X-Gm-Message-State: ABy/qLZ0iKqGICIOCnG6nSa0EHXuHU06DfsK4JlhOR5VqMMkyyTdlpdg qlyMNF4OOPjz+4D2ZL1pTdcaHQ== X-Google-Smtp-Source: APBJJlEzpqwQtx1kmMczULPSvuYG77OrcY8I3p5ckaYrRJ+QUk4Nz+w0rmrKMaE9Kfm2V17UDeA/SQ== X-Received: by 2002:a17:906:11a:b0:993:f349:c989 with SMTP id 26-20020a170906011a00b00993f349c989mr10926795eje.7.1691051567156; Thu, 03 Aug 2023 01:32:47 -0700 (PDT) Received: from phenom.ffwll.local ([2a02:168:57f4:0:efd0:b9e5:5ae6:c2fa]) by smtp.gmail.com with ESMTPSA id x24-20020a170906135800b009930308425csm10124169ejb.31.2023.08.03.01.32.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 03 Aug 2023 01:32:46 -0700 (PDT) Date: Thu, 3 Aug 2023 10:32:44 +0200 From: Daniel Vetter To: "Kasireddy, Vivek" Cc: Daniel Vetter , "dri-devel@lists.freedesktop.org" , "linux-mm@kvack.org" , "Kim, Dongwon" , David Hildenbrand , "Chang, Junxiao" , Hugh Dickins , Peter Xu , Gerd Hoffmann , Jason Gunthorpe , Mike Kravetz Subject: Re: [RFC v1 2/3] udmabuf: Replace pages when there is FALLOC_FL_PUNCH_HOLE in memfd Message-ID: Mail-Followup-To: "Kasireddy, Vivek" , "dri-devel@lists.freedesktop.org" , "linux-mm@kvack.org" , "Kim, Dongwon" , David Hildenbrand , "Chang, Junxiao" , Hugh Dickins , Peter Xu , Gerd Hoffmann , Jason Gunthorpe , Mike Kravetz References: <20230718082858.1570809-1-vivek.kasireddy@intel.com> <20230718082858.1570809-3-vivek.kasireddy@intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: X-Operating-System: Linux phenom 6.3.0-2-amd64 X-Rspamd-Queue-Id: 07779180005 X-Rspam-User: X-Rspamd-Server: rspam05 X-Stat-Signature: kmqndbbud8c1u7kdp8bapx3oezoz58j9 X-HE-Tag: 1691051568-100908 X-HE-Meta: U2FsdGVkX18w4g2R+grysh4KkJ+d4jLo/rZifmL526jBi+TIhjIfqwxCe6dqXjbPKM0UlZ0AA8sxWpioT8nryGpZWWZfLIpvpdJbVBKWKkEvVw44YTg9mwhas0tonOUXQZT4XuE6j5UoSeH5sjP3DyVV1n4FD+nhu1gDa0rCIw6w0V2Ihp7sGc1T+7GPd546brFlqMjFLxMrlzsOQKIQkoiikO9M3opE/SpBWscM3pwAS3IHbJ1auO9l+yc/AQaIVOObb5xdRbSTmGejUcJmlaN1VpTa3PPFdopABy/xvK46VVaZYpOAotV5hERv7J9UcEuGAJmDUp1U9EDYQ/I8uODNz8xA82F+5FeZ6tGtcOxAQqF35SAE7+nB4J1u2Hnx7bLCZkptPWyVJMmi4GP1ioC/BnwjXXXPfIlbvVcvGKjR6bGFf1/JjFgDr5IMlb0KStkAQlNmvixm8ZNPyiAqUVcXlhyK/Ikz2aAwU6RU6BY1h/YqsQc/1pd+hJH2JKzVPy5dz7gqyQItjvmqADiuLLdjyz5gtTUU6mPT5HoqwRM74v3fo9MFdKIOVDZnkRIfyNl5CKOjUkXw7rTeumAEhRA+QLeE4wjxUcAngBDBiVpD3YKwgSipbVohyEro/KGu/o2bIic5y8nft2gLMghZcue0GRMEYLp9I4y8kv3S8g46IRS98JMVraHl01b/33LgGl/OXg/62TzoFG8hIG0rJzWCsBZ0fvwBwGVPvYyNs3VfnSjn0b+w1SVxcSbftzwIaC1xDcwdjta4c8unJbNr4Ct42F1VLhyRnd2Wf6NX7JXGXWhRtArv4p7qz+Pfusxz/MpyIqnMbH8szXFzBFUBJV9srHrG9KgzFh3Z3IfM4lJBLTsV8nxiI48UVXWIwVUIezz9zxf/F/YN6Ptqi6cgZ2QJJQ8Hgb8NYySy9GeKJkmyR90Myl/kgjqUGSm4efQNNqd4+r7n2PAVlw/nyWj kPduWqqk uC9yDz4EIl2edS0uCHCXYg07kCeYYEvCaAnQUwzG60ndSIIyyVD3131g07l2xPr35Rs2lDr7pX1LBCK1Uq6skC6/OTpOhV6SyW6GhMrsKy4UrkZwOQcP4PSioDuQfchmzlwm6ft/wkl6y41ANEjWdojv4mEqakTSgoJRx1B4FXuMldp8iu90TqzynurDY0sku8tSC027/k+dSf4GE8DGCuHZXtGOjQuL/O5s/BEcGjD3Pz0avtz40GyZ74gAUNvASlvJ1qlVB7iWjxMzT/r9puseb2BGQv6wa9/d0hK0lmuj+g1+fzwXexaBFen6u5P28cILaku3f5AGgUi8hEbb6hs0WeALnZwMZBLEEn3VRET2CIhTfo/TptcFkgeZ3Z0HohsWbTVSrEDcKGfgdz9JgkvjrslXLKHSNz332kNrHP0+fl496d3YKhyvFE/nBWfJtD/eUuW9+UEYfY2T8hXsU0YnEV+BCdjk3xsU0zYgJGEemn60c3FQhpcrLtEsjzUWCgXZH X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: On Thu, Aug 03, 2023 at 08:24:07AM +0000, Kasireddy, Vivek wrote: > Hi Daniel, > > > > > On Tue, Jul 18, 2023 at 01:28:57AM -0700, Vivek Kasireddy wrote: > > > When a hole is punched in the memfd or when a page is replaced for > > > any reason, the udmabuf driver needs to get notified in order to > > > update its list of pages with the new page. To accomplish this, we > > > first identify the vma ranges where pages associated with a given > > > udmabuf are mapped to and then register a handler for update_mapping > > > mmu notifier for receiving mapping updates. > > > > > > Once we get notified about a new page faulted in at a given offset > > > in the mapping (backed by shmem or hugetlbfs), the list of pages > > > is updated and we also zap the relevant PTEs associated with the > > > vmas that have mmap'd the udmabuf fd. > > > > > > Cc: David Hildenbrand > > > Cc: Mike Kravetz > > > Cc: Hugh Dickins > > > Cc: Peter Xu > > > Cc: Jason Gunthorpe > > > Cc: Gerd Hoffmann > > > Cc: Dongwon Kim > > > Cc: Junxiao Chang > > > Signed-off-by: Vivek Kasireddy > > > > I think the long thread made it clear already, so just for the record: > > This wont work. udmabuf is very intentionally about pin_user_page > > semantics, if you change the underlying mapping, you get to keep all the > > pieces. > > > > The _only_ way to make this work by implementing the dma_buf move > > notification infrastructure, and most importers can't cope with such > > dynamic dma-buf. And so most likely will not solve your use-case. > Right, we do have to call move_notify() at some point to let the importers > know about the backing memory changes but as you suggest, unfortunately, > most importers don't handle moves. However, I guess I could try implementing > it in i915 and also add a helper in GEM. > > > > > Everything else races in a fundamental and unfixable way. > I think there might still be some options to address this use-case in a safe > and race-free way particularly given the fact that with udmabuf driver, > the writes and reads do not occur simultaneously. We use DMA fences > in both the Host and Guest to ensure this synchronization. One more I've forgotten. You cannot combine udmabuf with move_notify, the locking doesn't work. There's only three ways to make this happen: - You put the mmu_notifier into each driver, which means these (usually called userptr memory areas) are _not_ shareable as dma-buf. Every driver has to set up their own userptr mapping to make this work. - pin_user_pages, which is what udmabuf does - You make the dma-buf export allocator specific, because then you can more directly tie into the locking and bypass the gup/mmu_notifer rules. Might need a full rewrite of the allocator though, but at least in theory it should be possible to have a memfd ioctl to export as a dmabuf (with the only requirement that it needs to be size-sealed, because dma-buf never change size). Trying to pull off what you're trying to do with udmabuf either races or deadlocks. Cheers, Daniel > > Thanks, > Vivek > > > -Daniel > > > > > --- > > > drivers/dma-buf/udmabuf.c | 172 > > ++++++++++++++++++++++++++++++++++++++ > > > 1 file changed, 172 insertions(+) > > > > > > diff --git a/drivers/dma-buf/udmabuf.c b/drivers/dma-buf/udmabuf.c > > > index 10c47bf77fb5..189a36c41906 100644 > > > --- a/drivers/dma-buf/udmabuf.c > > > +++ b/drivers/dma-buf/udmabuf.c > > > @@ -4,6 +4,8 @@ > > > #include > > > #include > > > #include > > > +#include > > > +#include > > > #include > > > #include > > > #include > > > @@ -30,6 +32,23 @@ struct udmabuf { > > > struct sg_table *sg; > > > struct miscdevice *device; > > > pgoff_t *offsets; > > > + struct udmabuf_vma_range *ranges; > > > + unsigned int num_ranges; > > > + struct mmu_notifier notifier; > > > + struct mutex mn_lock; > > > + struct list_head mmap_vmas; > > > +}; > > > + > > > +struct udmabuf_vma_range { > > > + struct file *memfd; > > > + pgoff_t ubufindex; > > > + unsigned long start; > > > + unsigned long end; > > > +}; > > > + > > > +struct udmabuf_mmap_vma { > > > + struct list_head vma_link; > > > + struct vm_area_struct *vma; > > > }; > > > > > > static vm_fault_t udmabuf_vm_fault(struct vm_fault *vmf) > > > @@ -42,28 +61,54 @@ static vm_fault_t udmabuf_vm_fault(struct > > vm_fault *vmf) > > > if (pgoff >= ubuf->pagecount) > > > return VM_FAULT_SIGBUS; > > > > > > + mutex_lock(&ubuf->mn_lock); > > > pfn = page_to_pfn(ubuf->pages[pgoff]); > > > if (ubuf->offsets) { > > > pfn += ubuf->offsets[pgoff] >> PAGE_SHIFT; > > > } > > > + mutex_unlock(&ubuf->mn_lock); > > > > > > return vmf_insert_pfn(vma, vmf->address, pfn); > > > } > > > > > > +static void udmabuf_vm_close(struct vm_area_struct *vma) > > > +{ > > > + struct udmabuf *ubuf = vma->vm_private_data; > > > + struct udmabuf_mmap_vma *mmap_vma; > > > + > > > + list_for_each_entry(mmap_vma, &ubuf->mmap_vmas, vma_link) { > > > + if (mmap_vma->vma == vma) { > > > + list_del(&mmap_vma->vma_link); > > > + kfree(mmap_vma); > > > + break; > > > + } > > > + } > > > +} > > > + > > > static const struct vm_operations_struct udmabuf_vm_ops = { > > > .fault = udmabuf_vm_fault, > > > + .close = udmabuf_vm_close, > > > }; > > > > > > static int mmap_udmabuf(struct dma_buf *buf, struct vm_area_struct > > *vma) > > > { > > > struct udmabuf *ubuf = buf->priv; > > > + struct udmabuf_mmap_vma *mmap_vma; > > > > > > if ((vma->vm_flags & (VM_SHARED | VM_MAYSHARE)) == 0) > > > return -EINVAL; > > > > > > + mmap_vma = kmalloc(sizeof(*mmap_vma), GFP_KERNEL); > > > + if (!mmap_vma) > > > + return -ENOMEM; > > > + > > > vma->vm_ops = &udmabuf_vm_ops; > > > vma->vm_private_data = ubuf; > > > vm_flags_set(vma, VM_PFNMAP | VM_DONTEXPAND | > > VM_DONTDUMP); > > > + > > > + mmap_vma->vma = vma; > > > + list_add(&mmap_vma->vma_link, &ubuf->mmap_vmas); > > > + > > > return 0; > > > } > > > > > > @@ -109,6 +154,7 @@ static struct sg_table *get_sg_table(struct device > > *dev, struct dma_buf *buf, > > > if (ret < 0) > > > goto err_alloc; > > > > > > + mutex_lock(&ubuf->mn_lock); > > > for_each_sg(sg->sgl, sgl, ubuf->pagecount, i) { > > > offset = ubuf->offsets ? ubuf->offsets[i] : 0; > > > sg_set_page(sgl, ubuf->pages[i], PAGE_SIZE, offset); > > > @@ -116,9 +162,12 @@ static struct sg_table *get_sg_table(struct device > > *dev, struct dma_buf *buf, > > > ret = dma_map_sgtable(dev, sg, direction, 0); > > > if (ret < 0) > > > goto err_map; > > > + > > > + mutex_unlock(&ubuf->mn_lock); > > > return sg; > > > > > > err_map: > > > + mutex_unlock(&ubuf->mn_lock); > > > sg_free_table(sg); > > > err_alloc: > > > kfree(sg); > > > @@ -157,6 +206,9 @@ static void release_udmabuf(struct dma_buf *buf) > > > > > > for (pg = 0; pg < ubuf->pagecount; pg++) > > > put_page(ubuf->pages[pg]); > > > + > > > + mmu_notifier_unregister(&ubuf->notifier, ubuf->notifier.mm); > > > + kfree(ubuf->ranges); > > > kfree(ubuf->offsets); > > > kfree(ubuf->pages); > > > kfree(ubuf); > > > @@ -208,6 +260,93 @@ static const struct dma_buf_ops udmabuf_ops = { > > > .end_cpu_access = end_cpu_udmabuf, > > > }; > > > > > > +static void invalidate_mmap_vmas(struct udmabuf *ubuf, > > > + struct udmabuf_vma_range *range, > > > + unsigned long address, unsigned long size) > > > +{ > > > + struct udmabuf_mmap_vma *vma; > > > + unsigned long start = range->ubufindex << PAGE_SHIFT; > > > + > > > + start += address - range->start; > > > + list_for_each_entry(vma, &ubuf->mmap_vmas, vma_link) { > > > + zap_vma_ptes(vma->vma, vma->vma->vm_start + start, > > size); > > > + } > > > +} > > > + > > > +static struct udmabuf_vma_range *find_udmabuf_range(struct udmabuf > > *ubuf, > > > + unsigned long address) > > > +{ > > > + struct udmabuf_vma_range *range; > > > + int i; > > > + > > > + for (i = 0; i < ubuf->num_ranges; i++) { > > > + range = &ubuf->ranges[i]; > > > + if (address >= range->start && address < range->end) > > > + return range; > > > + } > > > + > > > + return NULL; > > > +} > > > + > > > +static void update_udmabuf(struct mmu_notifier *mn, struct mm_struct > > *mm, > > > + unsigned long address, unsigned long pfn) > > > +{ > > > + struct udmabuf *ubuf = container_of(mn, struct udmabuf, notifier); > > > + struct udmabuf_vma_range *range = find_udmabuf_range(ubuf, > > address); > > > + struct page *old_page, *new_page; > > > + pgoff_t pgoff, pgshift = PAGE_SHIFT; > > > + unsigned long size = 0; > > > + > > > + if (!range || !pfn_valid(pfn)) > > > + return; > > > + > > > + if (is_file_hugepages(range->memfd)) > > > + pgshift = huge_page_shift(hstate_file(range->memfd)); > > > + > > > + mutex_lock(&ubuf->mn_lock); > > > + pgoff = range->ubufindex + ((address - range->start) >> pgshift); > > > + old_page = ubuf->pages[pgoff]; > > > + new_page = pfn_to_page(pfn); > > > + > > > + do { > > > + ubuf->pages[pgoff] = new_page; > > > + get_page(new_page); > > > + put_page(old_page); > > > + size += PAGE_SIZE; > > > + } while (ubuf->pages[++pgoff] == old_page); > > > + > > > + mutex_unlock(&ubuf->mn_lock); > > > + invalidate_mmap_vmas(ubuf, range, address, size); > > > +} > > > + > > > +static const struct mmu_notifier_ops udmabuf_update_ops = { > > > + .update_mapping = update_udmabuf, > > > +}; > > > + > > > +static struct vm_area_struct *find_guest_ram_vma(struct udmabuf *ubuf, > > > + struct mm_struct > > *vmm_mm) > > > +{ > > > + struct vm_area_struct *vma = NULL; > > > + MA_STATE(mas, &vmm_mm->mm_mt, 0, 0); > > > + unsigned long addr; > > > + pgoff_t pg; > > > + > > > + mas_set(&mas, 0); > > > + mmap_read_lock(vmm_mm); > > > + mas_for_each(&mas, vma, ULONG_MAX) { > > > + for (pg = 0; pg < ubuf->pagecount; pg++) { > > > + addr = page_address_in_vma(ubuf->pages[pg], vma); > > > + if (addr == -EFAULT) > > > + break; > > > + } > > > + if (addr != -EFAULT) > > > + break; > > > + } > > > + mmap_read_unlock(vmm_mm); > > > + > > > + return vma; > > > +} > > > + > > > #define SEALS_WANTED (F_SEAL_SHRINK) > > > #define SEALS_DENIED (F_SEAL_WRITE) > > > > > > @@ -218,6 +357,7 @@ static long udmabuf_create(struct miscdevice > > *device, > > > DEFINE_DMA_BUF_EXPORT_INFO(exp_info); > > > struct file *memfd = NULL; > > > struct address_space *mapping = NULL; > > > + struct vm_area_struct *guest_ram; > > > struct udmabuf *ubuf; > > > struct dma_buf *buf; > > > pgoff_t pgoff, pgcnt, pgidx, pgbuf = 0, pglimit; > > > @@ -252,6 +392,13 @@ static long udmabuf_create(struct miscdevice > > *device, > > > goto err; > > > } > > > > > > + ubuf->ranges = kmalloc_array(head->count, sizeof(*ubuf->ranges), > > > + GFP_KERNEL); > > > + if (!ubuf->ranges) { > > > + ret = -ENOMEM; > > > + goto err; > > > + } > > > + > > > pgbuf = 0; > > > for (i = 0; i < head->count; i++) { > > > ret = -EBADFD; > > > @@ -270,6 +417,8 @@ static long udmabuf_create(struct miscdevice > > *device, > > > goto err; > > > pgoff = list[i].offset >> PAGE_SHIFT; > > > pgcnt = list[i].size >> PAGE_SHIFT; > > > + ubuf->ranges[i].ubufindex = pgbuf; > > > + ubuf->ranges[i].memfd = memfd; > > > if (is_file_hugepages(memfd)) { > > > if (!ubuf->offsets) { > > > ubuf->offsets = kmalloc_array(ubuf- > > >pagecount, > > > @@ -299,6 +448,7 @@ static long udmabuf_create(struct miscdevice > > *device, > > > get_page(hpage); > > > ubuf->pages[pgbuf] = hpage; > > > ubuf->offsets[pgbuf++] = chunkoff << > > PAGE_SHIFT; > > > + > > > if (++chunkoff == maxchunks) { > > > put_page(hpage); > > > hpage = NULL; > > > @@ -334,6 +484,25 @@ static long udmabuf_create(struct miscdevice > > *device, > > > goto err; > > > } > > > > > > + guest_ram = find_guest_ram_vma(ubuf, current->mm); > > > + if (!guest_ram) > > > + goto err; > > > + > > > + ubuf->notifier.ops = &udmabuf_update_ops; > > > + ret = mmu_notifier_register(&ubuf->notifier, current->mm); > > > + if (ret) > > > + goto err; > > > + > > > + ubuf->num_ranges = head->count; > > > + for (i = 0; i < ubuf->num_ranges; i++) { > > > + page = ubuf->pages[ubuf->ranges[i].ubufindex]; > > > + ubuf->ranges[i].start = page_address_in_vma(page, > > guest_ram); > > > + ubuf->ranges[i].end = ubuf->ranges[i].start + list[i].size; > > > + } > > > + > > > + INIT_LIST_HEAD(&ubuf->mmap_vmas); > > > + mutex_init(&ubuf->mn_lock); > > > + > > > flags = 0; > > > if (head->flags & UDMABUF_FLAGS_CLOEXEC) > > > flags |= O_CLOEXEC; > > > @@ -344,6 +513,9 @@ static long udmabuf_create(struct miscdevice > > *device, > > > put_page(ubuf->pages[--pgbuf]); > > > if (memfd) > > > fput(memfd); > > > + if (ubuf->notifier.mm) > > > + mmu_notifier_unregister(&ubuf->notifier, ubuf- > > >notifier.mm); > > > + kfree(ubuf->ranges); > > > kfree(ubuf->offsets); > > > kfree(ubuf->pages); > > > kfree(ubuf); > > > -- > > > 2.39.2 > > > > > > > -- > > Daniel Vetter > > Software Engineer, Intel Corporation > > http://blog.ffwll.ch -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch