Re: [PATCH rdma-next 2/6] RDMA/umem: Add API to find best driver supported page size in an MR

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Mon, Dec 24, 2018 at 04:32:23PM -0600, Shiraz Saleem wrote:
> This helper iterates through the SG list to find the best page size to use
> from a bitmap of HW supported page sizes. Drivers that support multiple
> page sizes, but not mixed pages in an MR can use this API.
> 
> Suggested-by: Jason Gunthorpe <jgg@xxxxxxxx>
> Reviewed-by: Michael J. Ruhl <michael.j.ruhl@xxxxxxxxx>
> Signed-off-by: Shiraz Saleem <shiraz.saleem@xxxxxxxxx>
>  drivers/infiniband/core/umem.c | 86 ++++++++++++++++++++++++++++++++++++++++++
>  include/rdma/ib_umem.h         |  9 +++++
>  2 files changed, 95 insertions(+)
> 
> diff --git a/drivers/infiniband/core/umem.c b/drivers/infiniband/core/umem.c
> index 64bacc5..b2f2d75 100644
> +++ b/drivers/infiniband/core/umem.c
> @@ -119,6 +119,92 @@ static void ib_umem_add_sg_table(struct scatterlist **cur,
>  }
>  
>  /**
> + * ib_umem_find_pg_bit - Find the page bit to use for phyaddr
> + *
> + * @phyaddr: Physical address after DMA translation
> + * @supported_pgsz: bitmask of HW supported page sizes
> + */
> +static unsigned int ib_umem_find_pg_bit(unsigned long phyaddr,
> +					unsigned long supported_pgsz)
> +{
> +	unsigned long num_zeroes;
> +	unsigned long pgsz;
> +
> +	/* Trailing zero bits in the address */
> +	num_zeroes = __ffs(phyaddr);
> +
> +	/* Find page bit such that phyaddr is aligned to the highest supported
> +	 * HW page size
> +	 */
> +	pgsz = supported_pgsz & (BIT_ULL(num_zeroes + 1) - 1);
> +	if (!pgsz)
> +		return __ffs(supported_pgsz);
> +
> +	return (fls64(pgsz) - 1);

extra brackets

> +}
> +
> +/**
> + * ib_umem_find_single_pg_size - Find best HW page size to use for this MR
> + * @umem: umem struct
> + * @supported_pgsz: bitmask of HW supported page sizes
> + * @uvirt_addr: user-space virtual MR base address
> + *
> + * This helper is intended for HW that support multiple page
> + * sizes but can do only a single page size in an MR.

Returns 0 if the umem requires page sizes not supported by the driver
to be mapped. Drivers always supporting PAGE_SIZE will never see a 0
result.

> + */
> +unsigned long ib_umem_find_single_pg_size(struct ib_umem *umem,
> +					  unsigned long supported_pgsz,
> +					  unsigned long uvirt_addr)
> +{
> +	struct scatterlist *sg;
> +	unsigned int pg_bit_sg, min_pg_bit, best_pg_bit;
> +	int i;
> +
> +	if (!supported_pgsz)
> +		return 0;

Maybe like:

if (WARN_ON(!(BIT_ULL(PAGE_SHIFT) & supported_pgsz)))
     return 0;

?

Drivers are not allowed to not support the system page size.

And also I guess it would be reasonable to have something like

/* Driver only supports the system page size, so no further checks required */
if (supported_pgsz >> PAGE_SHIFT == 1)
        return PAGE_SIZE;

Otherwise I think this looks fine

Jason



[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Photo]     [Yosemite News]     [Yosemite Photos]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux