[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <776e17af-ae25-16a0-f443-66f3972b00c0@google.com>
Date: Thu, 14 Dec 2023 09:58:23 -0800 (PST)
From: David Rientjes <rientjes@...gle.com>
To: Pasha Tatashin <pasha.tatashin@...een.com>
cc: Andrew Morton <akpm@...ux-foundation.org>, alim.akhtar@...sung.com,
alyssa@...enzweig.io, asahi@...ts.linux.dev,
baolu.lu@...ux.intel.com, bhelgaas@...gle.com,
cgroups@...r.kernel.org, corbet@....net, david@...hat.com,
dwmw2@...radead.org, hannes@...xchg.org, heiko@...ech.de,
iommu@...ts.linux.dev, jernej.skrabec@...il.com,
jonathanh@...dia.com, joro@...tes.org,
krzysztof.kozlowski@...aro.org, linux-doc@...r.kernel.org,
linux-fsdevel@...r.kernel.org, linux-kernel@...r.kernel.org,
linux-mm@...ck.org, linux-rockchip@...ts.infradead.org,
linux-samsung-soc@...r.kernel.org, linux-sunxi@...ts.linux.dev,
linux-tegra@...r.kernel.org, lizefan.x@...edance.com,
marcan@...can.st, mhiramat@...nel.org, m.szyprowski@...sung.com,
paulmck@...nel.org, rdunlap@...radead.org, robin.murphy@....com,
samuel@...lland.org, suravee.suthikulpanit@....com,
sven@...npeter.dev, thierry.reding@...il.com, tj@...nel.org,
tomas.mudrunka@...il.com, vdumpa@...dia.com, wens@...e.org,
will@...nel.org, yu-cheng.yu@...el.com
Subject: Re: [PATCH v2 01/10] iommu/vt-d: add wrapper functions for page
allocations
On Thu, 30 Nov 2023, Pasha Tatashin wrote:
> diff --git a/drivers/iommu/iommu-pages.h b/drivers/iommu/iommu-pages.h
> new file mode 100644
> index 000000000000..2332f807d514
> --- /dev/null
> +++ b/drivers/iommu/iommu-pages.h
> @@ -0,0 +1,199 @@
> +/* SPDX-License-Identifier: GPL-2.0-only */
> +/*
> + * Copyright (c) 2023, Google LLC.
> + * Pasha Tatashin <pasha.tatashin@...een.com>
> + */
> +
> +#ifndef __IOMMU_PAGES_H
> +#define __IOMMU_PAGES_H
> +
> +#include <linux/vmstat.h>
> +#include <linux/gfp.h>
> +#include <linux/mm.h>
> +
> +/*
> + * All page allocation that are performed in the IOMMU subsystem must use one of
> + * the functions below. This is necessary for the proper accounting as IOMMU
> + * state can be rather large, i.e. multiple gigabytes in size.
> + */
> +
> +/**
> + * __iommu_alloc_pages_node - allocate a zeroed page of a given order from
> + * specific NUMA node.
> + * @nid: memory NUMA node id
NUMA_NO_NODE if no locality requirements?
> + * @gfp: buddy allocator flags
> + * @order: page order
> + *
> + * returns the head struct page of the allocated page.
> + */
> +static inline struct page *__iommu_alloc_pages_node(int nid, gfp_t gfp,
> + int order)
> +{
> + struct page *pages;
s/pages/page/ here and later in this file.
> +
> + pages = alloc_pages_node(nid, gfp | __GFP_ZERO, order);
> + if (!pages)
unlikely()?
> + return NULL;
> +
> + return pages;
> +}
> +
> +/**
> + * __iommu_alloc_pages - allocate a zeroed page of a given order.
> + * @gfp: buddy allocator flags
> + * @order: page order
> + *
> + * returns the head struct page of the allocated page.
> + */
> +static inline struct page *__iommu_alloc_pages(gfp_t gfp, int order)
> +{
> + struct page *pages;
> +
> + pages = alloc_pages(gfp | __GFP_ZERO, order);
> + if (!pages)
> + return NULL;
> +
> + return pages;
> +}
> +
> +/**
> + * __iommu_alloc_page_node - allocate a zeroed page at specific NUMA node.
> + * @nid: memory NUMA node id
> + * @gfp: buddy allocator flags
> + *
> + * returns the struct page of the allocated page.
> + */
> +static inline struct page *__iommu_alloc_page_node(int nid, gfp_t gfp)
> +{
> + return __iommu_alloc_pages_node(nid, gfp, 0);
> +}
> +
> +/**
> + * __iommu_alloc_page - allocate a zeroed page
> + * @gfp: buddy allocator flags
> + *
> + * returns the struct page of the allocated page.
> + */
> +static inline struct page *__iommu_alloc_page(gfp_t gfp)
> +{
> + return __iommu_alloc_pages(gfp, 0);
> +}
> +
> +/**
> + * __iommu_free_pages - free page of a given order
> + * @pages: head struct page of the page
I think "pages" implies more than one page, this is just a (potentially
compound) page?
> + * @order: page order
> + */
> +static inline void __iommu_free_pages(struct page *pages, int order)
> +{
> + if (!pages)
> + return;
> +
> + __free_pages(pages, order);
> +}
> +
> +/**
> + * __iommu_free_page - free page
> + * @page: struct page of the page
> + */
> +static inline void __iommu_free_page(struct page *page)
> +{
> + __iommu_free_pages(page, 0);
> +}
> +
> +/**
> + * iommu_alloc_pages_node - allocate a zeroed page of a given order from
> + * specific NUMA node.
> + * @nid: memory NUMA node id
> + * @gfp: buddy allocator flags
> + * @order: page order
> + *
> + * returns the virtual address of the allocated page
> + */
> +static inline void *iommu_alloc_pages_node(int nid, gfp_t gfp, int order)
> +{
> + struct page *pages = __iommu_alloc_pages_node(nid, gfp, order);
> +
> + if (!pages)
> + return NULL;
> +
> + return page_address(pages);
> +}
> +
> +/**
> + * iommu_alloc_pages - allocate a zeroed page of a given order
> + * @gfp: buddy allocator flags
> + * @order: page order
> + *
> + * returns the virtual address of the allocated page
> + */
> +static inline void *iommu_alloc_pages(gfp_t gfp, int order)
> +{
> + struct page *pages = __iommu_alloc_pages(gfp, order);
> +
> + if (!pages)
> + return NULL;
> +
> + return page_address(pages);
> +}
> +
> +/**
> + * iommu_alloc_page_node - allocate a zeroed page at specific NUMA node.
> + * @nid: memory NUMA node id
> + * @gfp: buddy allocator flags
> + *
> + * returns the virtual address of the allocated page
> + */
> +static inline void *iommu_alloc_page_node(int nid, gfp_t gfp)
> +{
> + return iommu_alloc_pages_node(nid, gfp, 0);
> +}
> +
> +/**
> + * iommu_alloc_page - allocate a zeroed page
> + * @gfp: buddy allocator flags
> + *
> + * returns the virtual address of the allocated page
> + */
> +static inline void *iommu_alloc_page(gfp_t gfp)
> +{
> + return iommu_alloc_pages(gfp, 0);
> +}
> +
> +/**
> + * iommu_free_pages - free page of a given order
> + * @virt: virtual address of the page to be freed.
> + * @order: page order
> + */
> +static inline void iommu_free_pages(void *virt, int order)
> +{
> + if (!virt)
> + return;
> +
> + __iommu_free_pages(virt_to_page(virt), order);
> +}
> +
> +/**
> + * iommu_free_page - free page
> + * @virt: virtual address of the page to be freed.
> + */
> +static inline void iommu_free_page(void *virt)
> +{
> + iommu_free_pages(virt, 0);
> +}
> +
> +/**
> + * iommu_free_pages_list - free a list of pages.
> + * @pages: the head of the lru list to be freed.
Document the locking requirements for this?
> + */
> +static inline void iommu_free_pages_list(struct list_head *pages)
> +{
> + while (!list_empty(pages)) {
> + struct page *p = list_entry(pages->prev, struct page, lru);
> +
> + list_del(&p->lru);
> + put_page(p);
> + }
> +}
> +
> +#endif /* __IOMMU_PAGES_H */
> --
> 2.43.0.rc2.451.g8631bc7472-goog
>
>
>
Powered by blists - more mailing lists