diff options
author | Julian Wiedmann <jwi@linux.ibm.com> | 2020-04-02 23:30:41 +0200 |
---|---|---|
committer | Vasily Gorbik <gor@linux.ibm.com> | 2020-04-28 13:49:47 +0200 |
commit | 2a7cf35c4056facd35c952e8000519034376eef7 (patch) | |
tree | e830012ff454a9cf367891b4af164eca072b884d /drivers/s390/cio/qdio_setup.c | |
parent | s390/qdio: do more fine-grained allocation roll-back (diff) | |
download | linux-2a7cf35c4056facd35c952e8000519034376eef7.tar.xz linux-2a7cf35c4056facd35c952e8000519034376eef7.zip |
s390/qdio: roll-back after queue allocation error
When qdio_allocate_qs() fails, have it deal with its previous
allocations.
This way qdio_allocate() doesn't need to clean up afterwards.
Signed-off-by: Julian Wiedmann <jwi@linux.ibm.com>
Reviewed-by: Steffen Maier <maier@linux.ibm.com>
Reviewed-by: Benjamin Block <bblock@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Diffstat (limited to 'drivers/s390/cio/qdio_setup.c')
-rw-r--r-- | drivers/s390/cio/qdio_setup.c | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/drivers/s390/cio/qdio_setup.c b/drivers/s390/cio/qdio_setup.c index 51dc9a41555a..ebe61cbed443 100644 --- a/drivers/s390/cio/qdio_setup.c +++ b/drivers/s390/cio/qdio_setup.c @@ -135,6 +135,18 @@ output: } } +static void __qdio_free_queues(struct qdio_q **queues, unsigned int count) +{ + struct qdio_q *q; + unsigned int i; + + for (i = 0; i < count; i++) { + q = queues[i]; + free_page((unsigned long) q->slib); + kmem_cache_free(qdio_q_cache, q); + } +} + static int __qdio_allocate_qs(struct qdio_q **irq_ptr_qs, int nr_queues) { struct qdio_q *q; @@ -142,12 +154,15 @@ static int __qdio_allocate_qs(struct qdio_q **irq_ptr_qs, int nr_queues) for (i = 0; i < nr_queues; i++) { q = kmem_cache_zalloc(qdio_q_cache, GFP_KERNEL); - if (!q) + if (!q) { + __qdio_free_queues(irq_ptr_qs, i); return -ENOMEM; + } q->slib = (struct slib *) __get_free_page(GFP_KERNEL); if (!q->slib) { kmem_cache_free(qdio_q_cache, q); + __qdio_free_queues(irq_ptr_qs, i); return -ENOMEM; } irq_ptr_qs[i] = q; @@ -162,7 +177,11 @@ int qdio_allocate_qs(struct qdio_irq *irq_ptr, int nr_input_qs, int nr_output_qs rc = __qdio_allocate_qs(irq_ptr->input_qs, nr_input_qs); if (rc) return rc; + rc = __qdio_allocate_qs(irq_ptr->output_qs, nr_output_qs); + if (rc) + __qdio_free_queues(irq_ptr->input_qs, nr_input_qs); + return rc; } |