lkml.org 
[lkml]   [2016]   [Jun]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH net-next V4 3/6] ptr_ring: support resizing multiple queues
    Date
    From: "Michael S. Tsirkin" <mst@redhat.com>

    Sometimes, we need support resizing multiple queues at once. This is
    because it was not easy to recover to recover from a partial failure
    of multiple queues resizing.

    Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
    Signed-off-by: Jason Wang <jasowang@redhat.com>
    ---
    include/linux/ptr_ring.h | 71 +++++++++++++++++++++++++++++++++++-----
    tools/virtio/ringtest/ptr_ring.c | 5 +++
    2 files changed, 67 insertions(+), 9 deletions(-)

    diff --git a/include/linux/ptr_ring.h b/include/linux/ptr_ring.h
    index d78b8b8..2052011 100644
    --- a/include/linux/ptr_ring.h
    +++ b/include/linux/ptr_ring.h
    @@ -349,20 +349,14 @@ static inline int ptr_ring_init(struct ptr_ring *r, int size, gfp_t gfp)
    return 0;
    }

    -static inline int ptr_ring_resize(struct ptr_ring *r, int size, gfp_t gfp,
    - void (*destroy)(void *))
    +static inline void **__ptr_ring_swap_queue(struct ptr_ring *r, void **queue,
    + int size, gfp_t gfp,
    + void (*destroy)(void *))
    {
    - unsigned long flags;
    int producer = 0;
    - void **queue = __ptr_ring_init_queue_alloc(size, gfp);
    void **old;
    void *ptr;

    - if (!queue)
    - return -ENOMEM;
    -
    - spin_lock_irqsave(&(r)->producer_lock, flags);
    -
    while ((ptr = ptr_ring_consume(r)))
    if (producer < size)
    queue[producer++] = ptr;
    @@ -375,6 +369,23 @@ static inline int ptr_ring_resize(struct ptr_ring *r, int size, gfp_t gfp,
    old = r->queue;
    r->queue = queue;

    + return old;
    +}
    +
    +static inline int ptr_ring_resize(struct ptr_ring *r, int size, gfp_t gfp,
    + void (*destroy)(void *))
    +{
    + unsigned long flags;
    + void **queue = __ptr_ring_init_queue_alloc(size, gfp);
    + void **old;
    +
    + if (!queue)
    + return -ENOMEM;
    +
    + spin_lock_irqsave(&(r)->producer_lock, flags);
    +
    + old = __ptr_ring_swap_queue(r, queue, size, gfp, destroy);
    +
    spin_unlock_irqrestore(&(r)->producer_lock, flags);

    kfree(old);
    @@ -382,6 +393,48 @@ static inline int ptr_ring_resize(struct ptr_ring *r, int size, gfp_t gfp,
    return 0;
    }

    +static inline int ptr_ring_resize_multiple(struct ptr_ring **rings, int nrings,
    + int size,
    + gfp_t gfp, void (*destroy)(void *))
    +{
    + unsigned long flags;
    + void ***queues;
    + int i;
    +
    + queues = kmalloc(nrings * sizeof *queues, gfp);
    + if (!queues)
    + goto noqueues;
    +
    + for (i = 0; i < nrings; ++i) {
    + queues[i] = __ptr_ring_init_queue_alloc(size, gfp);
    + if (!queues[i])
    + goto nomem;
    + }
    +
    + for (i = 0; i < nrings; ++i) {
    + spin_lock_irqsave(&(rings[i])->producer_lock, flags);
    + queues[i] = __ptr_ring_swap_queue(rings[i], queues[i],
    + size, gfp, destroy);
    + spin_unlock_irqrestore(&(rings[i])->producer_lock, flags);
    + }
    +
    + for (i = 0; i < nrings; ++i)
    + kfree(queues[i]);
    +
    + kfree(queues);
    +
    + return 0;
    +
    +nomem:
    + while (--i >= 0)
    + kfree(queues[i]);
    +
    + kfree(queues);
    +
    +noqueues:
    + return -ENOMEM;
    +}
    +
    static inline void ptr_ring_cleanup(struct ptr_ring *r, void (*destroy)(void *))
    {
    void *ptr;
    diff --git a/tools/virtio/ringtest/ptr_ring.c b/tools/virtio/ringtest/ptr_ring.c
    index 74abd74..68e4f9f 100644
    --- a/tools/virtio/ringtest/ptr_ring.c
    +++ b/tools/virtio/ringtest/ptr_ring.c
    @@ -17,6 +17,11 @@
    typedef pthread_spinlock_t spinlock_t;

    typedef int gfp_t;
    +static void *kmalloc(unsigned size, gfp_t gfp)
    +{
    + return memalign(64, size);
    +}
    +
    static void *kzalloc(unsigned size, gfp_t gfp)
    {
    void *p = memalign(64, size);
    --
    2.7.4
    \
     
     \ /
      Last update: 2016-06-30 09:41    [W:2.374 / U:1.296 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site