Message ID | 17-v1-416f64558c7c+2a5-iommu_pages_jgg@nvidia.com |
---|---|
State | New |
Headers | show |
Series | iommu: Further abstract iommu-pages | expand |
On Tue, Feb 04, 2025 at 02:34:58PM -0400, Jason Gunthorpe wrote: > One part of RISCV already has a computed size, the other part seems to use > PAGE_SIZE (which is probably SZ_4K?). Convert the call. > > Signed-off-by: Jason Gunthorpe <jgg@nvidia.com> > --- > drivers/iommu/riscv/iommu.c | 15 ++++++++------- > 1 file changed, 8 insertions(+), 7 deletions(-) > > diff --git a/drivers/iommu/riscv/iommu.c b/drivers/iommu/riscv/iommu.c > index 549bd8d0615d75..b7cee3d651b179 100644 > --- a/drivers/iommu/riscv/iommu.c > +++ b/drivers/iommu/riscv/iommu.c > @@ -65,13 +65,15 @@ static int riscv_iommu_devres_pages_match(struct device *dev, void *res, void *p > return devres->addr == target->addr; > } > > -static void *riscv_iommu_get_pages(struct riscv_iommu_device *iommu, int order) > +static void *riscv_iommu_get_pages(struct riscv_iommu_device *iommu, > + unsigned int size) > { > struct riscv_iommu_devres *devres; > void *addr; > > - addr = iommu_alloc_pages_node(dev_to_node(iommu->dev), > - GFP_KERNEL_ACCOUNT, order); > + addr = iommu_alloc_pages_node_lg2(dev_to_node(iommu->dev), > + GFP_KERNEL_ACCOUNT, > + order_base_2(size)); > if (unlikely(!addr)) > return NULL; > > @@ -161,9 +163,8 @@ static int riscv_iommu_queue_alloc(struct riscv_iommu_device *iommu, > } else { > do { > const size_t queue_size = entry_size << (logsz + 1); > - const int order = get_order(queue_size); > > - queue->base = riscv_iommu_get_pages(iommu, order); > + queue->base = riscv_iommu_get_pages(iommu, queue_size); > queue->phys = __pa(queue->base); All allocations must be 4k aligned, including sub-page allocs. Note from IOMMU/RISC-V spec: "If the command-queue has 256 or fewer entries then the base address of the queue is always aligned to 4-KiB." I can't find this to be guaranteed with new allocation API. > } while (!queue->base && logsz-- > 0); > } > @@ -618,7 +619,7 @@ static struct riscv_iommu_dc *riscv_iommu_get_dc(struct riscv_iommu_device *iomm > break; > } > > - ptr = riscv_iommu_get_pages(iommu, 0); > + ptr = riscv_iommu_get_pages(iommu, PAGE_SIZE); > if (!ptr) > return NULL; > > @@ -698,7 +699,7 @@ static int riscv_iommu_iodir_alloc(struct riscv_iommu_device *iommu) > } > > if (!iommu->ddt_root) { > - iommu->ddt_root = riscv_iommu_get_pages(iommu, 0); > + iommu->ddt_root = riscv_iommu_get_pages(iommu, PAGE_SIZE); > iommu->ddt_phys = __pa(iommu->ddt_root); > } > > -- > 2.43.0 > best, - Tomasz
On Wed, Feb 05, 2025 at 09:30:05PM -0800, Tomasz Jeznach wrote: > > @@ -161,9 +163,8 @@ static int riscv_iommu_queue_alloc(struct riscv_iommu_device *iommu, > > } else { > > do { > > const size_t queue_size = entry_size << (logsz + 1); > > - const int order = get_order(queue_size); > > > > - queue->base = riscv_iommu_get_pages(iommu, order); > > + queue->base = riscv_iommu_get_pages(iommu, queue_size); > > queue->phys = __pa(queue->base); > > All allocations must be 4k aligned, including sub-page allocs. Oh weird, so it requires 4k alignment but the HW can refuse to support a 4k queue length? I changed it to this: + queue->base = riscv_iommu_get_pages( + iommu, max(queue_size, SZ_4K)); > > } while (!queue->base && logsz-- > 0); > > } > > @@ -618,7 +619,7 @@ static struct riscv_iommu_dc *riscv_iommu_get_dc(struct riscv_iommu_device *iomm > > break; > > } > > > > - ptr = riscv_iommu_get_pages(iommu, 0); > > + ptr = riscv_iommu_get_pages(iommu, PAGE_SIZE); > > if (!ptr) > > return NULL; > > > > @@ -698,7 +699,7 @@ static int riscv_iommu_iodir_alloc(struct riscv_iommu_device *iommu) > > } > > > > if (!iommu->ddt_root) { > > - iommu->ddt_root = riscv_iommu_get_pages(iommu, 0); > > + iommu->ddt_root = riscv_iommu_get_pages(iommu, PAGE_SIZE); > > iommu->ddt_phys = __pa(iommu->ddt_root); > > } Should these be SZ_4K as well or PAGE_SIZE? Thanks, Jason
On Thu, Feb 06, 2025 at 09:17:21AM -0400, Jason Gunthorpe wrote: > On Wed, Feb 05, 2025 at 09:30:05PM -0800, Tomasz Jeznach wrote: > > > @@ -161,9 +163,8 @@ static int riscv_iommu_queue_alloc(struct riscv_iommu_device *iommu, > > > } else { > > > do { > > > const size_t queue_size = entry_size << (logsz + 1); > > > - const int order = get_order(queue_size); > > > > > > - queue->base = riscv_iommu_get_pages(iommu, order); > > > + queue->base = riscv_iommu_get_pages(iommu, queue_size); > > > queue->phys = __pa(queue->base); > > > > All allocations must be 4k aligned, including sub-page allocs. > > Oh weird, so it requires 4k alignment but the HW can refuse to support > a 4k queue length? > Spec allows that. Also, hardware accepts only physical page number (so far PAGE_SIZE == 4K for riscv) of the base address, ignoring page offset. > I changed it to this: > > + queue->base = riscv_iommu_get_pages( > + iommu, max(queue_size, SZ_4K)); > LGTM > > > } while (!queue->base && logsz-- > 0); > > > } > > > @@ -618,7 +619,7 @@ static struct riscv_iommu_dc *riscv_iommu_get_dc(struct riscv_iommu_device *iomm > > > break; > > > } > > > > > > - ptr = riscv_iommu_get_pages(iommu, 0); > > > + ptr = riscv_iommu_get_pages(iommu, PAGE_SIZE); > > > if (!ptr) > > > return NULL; > > > > > > @@ -698,7 +699,7 @@ static int riscv_iommu_iodir_alloc(struct riscv_iommu_device *iommu) > > > } > > > > > > if (!iommu->ddt_root) { > > > - iommu->ddt_root = riscv_iommu_get_pages(iommu, 0); > > > + iommu->ddt_root = riscv_iommu_get_pages(iommu, PAGE_SIZE); > > > iommu->ddt_phys = __pa(iommu->ddt_root); > > > } > > Should these be SZ_4K as well or PAGE_SIZE? > SZ_4K. For now iommu/risc-v hardware always assumes PAGE_SIZE == 4K. > Thanks, > Jason Thanks, - Tomasz
diff --git a/drivers/iommu/riscv/iommu.c b/drivers/iommu/riscv/iommu.c index 549bd8d0615d75..b7cee3d651b179 100644 --- a/drivers/iommu/riscv/iommu.c +++ b/drivers/iommu/riscv/iommu.c @@ -65,13 +65,15 @@ static int riscv_iommu_devres_pages_match(struct device *dev, void *res, void *p return devres->addr == target->addr; } -static void *riscv_iommu_get_pages(struct riscv_iommu_device *iommu, int order) +static void *riscv_iommu_get_pages(struct riscv_iommu_device *iommu, + unsigned int size) { struct riscv_iommu_devres *devres; void *addr; - addr = iommu_alloc_pages_node(dev_to_node(iommu->dev), - GFP_KERNEL_ACCOUNT, order); + addr = iommu_alloc_pages_node_lg2(dev_to_node(iommu->dev), + GFP_KERNEL_ACCOUNT, + order_base_2(size)); if (unlikely(!addr)) return NULL; @@ -161,9 +163,8 @@ static int riscv_iommu_queue_alloc(struct riscv_iommu_device *iommu, } else { do { const size_t queue_size = entry_size << (logsz + 1); - const int order = get_order(queue_size); - queue->base = riscv_iommu_get_pages(iommu, order); + queue->base = riscv_iommu_get_pages(iommu, queue_size); queue->phys = __pa(queue->base); } while (!queue->base && logsz-- > 0); } @@ -618,7 +619,7 @@ static struct riscv_iommu_dc *riscv_iommu_get_dc(struct riscv_iommu_device *iomm break; } - ptr = riscv_iommu_get_pages(iommu, 0); + ptr = riscv_iommu_get_pages(iommu, PAGE_SIZE); if (!ptr) return NULL; @@ -698,7 +699,7 @@ static int riscv_iommu_iodir_alloc(struct riscv_iommu_device *iommu) } if (!iommu->ddt_root) { - iommu->ddt_root = riscv_iommu_get_pages(iommu, 0); + iommu->ddt_root = riscv_iommu_get_pages(iommu, PAGE_SIZE); iommu->ddt_phys = __pa(iommu->ddt_root); }
One part of RISCV already has a computed size, the other part seems to use PAGE_SIZE (which is probably SZ_4K?). Convert the call. Signed-off-by: Jason Gunthorpe <jgg@nvidia.com> --- drivers/iommu/riscv/iommu.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-)