2022-04-21 23:51:17

by Boris Ostrovsky

[permalink] [raw]
Subject: Re: [PATCH 09/18] xen/xenbus: add xenbus_setup_ring() service function


On 4/20/22 11:09 AM, Juergen Gross wrote:
>
> +/*
> + * xenbus_setup_ring
> + * @dev: xenbus device
> + * @vaddr: pointer to starting virtual address of the ring
> + * @nr_pages: number of pages to be granted
> + * @grefs: grant reference array to be filled in
> + *
> + * Allocate physically contiguous pages for a shared ring buffer and grant it
> + * to the peer of the given device. The ring buffer is initially filled with
> + * zeroes. The virtual address of the ring is stored at @vaddr and the
> + * grant references are stored in the @grefs array. In case of error @vaddr
> + * will be set to NULL and @grefs will be filled with INVALID_GRANT_REF.
> + */
> +int xenbus_setup_ring(struct xenbus_device *dev, gfp_t gfp, void **vaddr,
> + unsigned int nr_pages, grant_ref_t *grefs)
> +{
> + unsigned long ring_size = nr_pages * XEN_PAGE_SIZE;
> + unsigned int i;
> + int ret;
> +
> + *vaddr = alloc_pages_exact(ring_size, gfp | __GFP_ZERO);
> + if (!*vaddr) {
> + ret = -ENOMEM;
> + goto err;
> + }
> +
> + ret = xenbus_grant_ring(dev, *vaddr, nr_pages, grefs);
> + if (ret)
> + goto err;
> +
> + return 0;
> +
> + err:
> + if (*vaddr)
> + free_pages_exact(*vaddr, ring_size);
> + for (i = 0; i < nr_pages; i++)
> + grefs[i] = INVALID_GRANT_REF;
> + *vaddr = NULL;
> +
> + return ret;
> +}


We can create a wrapper around this function that will also call SHARED_RING_INIT() and FRONT_RING_INIT(). A bunch of drivers do that.


-boris


2022-04-22 22:43:35

by Jürgen Groß

[permalink] [raw]
Subject: Re: [PATCH 09/18] xen/xenbus: add xenbus_setup_ring() service function

On 20.04.22 20:44, Boris Ostrovsky wrote:
>
> On 4/20/22 11:09 AM, Juergen Gross wrote:
>> +/*
>> + * xenbus_setup_ring
>> + * @dev: xenbus device
>> + * @vaddr: pointer to starting virtual address of the ring
>> + * @nr_pages: number of pages to be granted
>> + * @grefs: grant reference array to be filled in
>> + *
>> + * Allocate physically contiguous pages for a shared ring buffer and grant it
>> + * to the peer of the given device. The ring buffer is initially filled with
>> + * zeroes. The virtual address of the ring is stored at @vaddr and the
>> + * grant references are stored in the @grefs array. In case of error @vaddr
>> + * will be set to NULL and @grefs will be filled with INVALID_GRANT_REF.
>> + */
>> +int xenbus_setup_ring(struct xenbus_device *dev, gfp_t gfp, void **vaddr,
>> +              unsigned int nr_pages, grant_ref_t *grefs)
>> +{
>> +    unsigned long ring_size = nr_pages * XEN_PAGE_SIZE;
>> +    unsigned int i;
>> +    int ret;
>> +
>> +    *vaddr = alloc_pages_exact(ring_size, gfp | __GFP_ZERO);
>> +    if (!*vaddr) {
>> +        ret = -ENOMEM;
>> +        goto err;
>> +    }
>> +
>> +    ret = xenbus_grant_ring(dev, *vaddr, nr_pages, grefs);
>> +    if (ret)
>> +        goto err;
>> +
>> +    return 0;
>> +
>> + err:
>> +    if (*vaddr)
>> +        free_pages_exact(*vaddr, ring_size);
>> +    for (i = 0; i < nr_pages; i++)
>> +        grefs[i] = INVALID_GRANT_REF;
>> +    *vaddr = NULL;
>> +
>> +    return ret;
>> +}
>
>
> We can create a wrapper around this function that will also call
> SHARED_RING_INIT() and FRONT_RING_INIT(). A bunch of drivers do that.

This wrapper would need to be a macro, so I decided not to do that.

It would make sense to merge the call of SHARED_RING_INIT() into
FRONT_RING_INIT() (or better, have a new macro combining the two),
though, as there is no use case of FRONT_RING_INIT() without a
call of SHARED_RING_INIT() directly before it.


Juergen


Attachments:
OpenPGP_0xB0DE9DD628BF132F.asc (3.08 kB)
OpenPGP public key
OpenPGP_signature (505.00 B)
OpenPGP digital signature
Download all attachments