mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-24 18:20:52 +07:00
s390/qdio: do more fine-grained allocation roll-back
Instead of having a catch-all qdio_release_memory() helper, free the individual allocations from the respective error path. 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>
This commit is contained in:
parent
3050f022df
commit
edbf3b2a87
@ -388,7 +388,7 @@ int qdio_setup_get_ssqd(struct qdio_irq *irq_ptr,
|
||||
int qdio_setup_irq(struct qdio_irq *irq_ptr, struct qdio_initialize *init_data);
|
||||
void qdio_shutdown_irq(struct qdio_irq *irq);
|
||||
void qdio_print_subchannel_info(struct qdio_irq *irq_ptr);
|
||||
void qdio_release_memory(struct qdio_irq *irq_ptr);
|
||||
void qdio_free_queues(struct qdio_irq *irq_ptr);
|
||||
int qdio_setup_init(void);
|
||||
void qdio_setup_exit(void);
|
||||
int qdio_enable_async_operation(struct qdio_output_q *q);
|
||||
|
@ -1205,7 +1205,10 @@ int qdio_free(struct ccw_device *cdev)
|
||||
cdev->private->qdio_data = NULL;
|
||||
mutex_unlock(&irq_ptr->setup_mutex);
|
||||
|
||||
qdio_release_memory(irq_ptr);
|
||||
qdio_free_queues(irq_ptr);
|
||||
free_page((unsigned long) irq_ptr->qdr);
|
||||
free_page(irq_ptr->chsc_page);
|
||||
free_page((unsigned long) irq_ptr);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qdio_free);
|
||||
@ -1221,6 +1224,7 @@ int qdio_allocate(struct ccw_device *cdev, unsigned int no_input_qs,
|
||||
{
|
||||
struct subchannel_id schid;
|
||||
struct qdio_irq *irq_ptr;
|
||||
int rc = -ENOMEM;
|
||||
|
||||
ccw_device_get_schid(cdev, &schid);
|
||||
DBF_EVENT("qallocate:%4x", schid.sch_no);
|
||||
@ -1232,12 +1236,12 @@ int qdio_allocate(struct ccw_device *cdev, unsigned int no_input_qs,
|
||||
/* irq_ptr must be in GFP_DMA since it contains ccw1.cda */
|
||||
irq_ptr = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
|
||||
if (!irq_ptr)
|
||||
goto out_err;
|
||||
return -ENOMEM;
|
||||
|
||||
irq_ptr->cdev = cdev;
|
||||
mutex_init(&irq_ptr->setup_mutex);
|
||||
if (qdio_allocate_dbf(irq_ptr))
|
||||
goto out_rel;
|
||||
goto err_dbf;
|
||||
|
||||
DBF_DEV_EVENT(DBF_ERR, irq_ptr, "alloc niq:%1u noq:%1u", no_input_qs,
|
||||
no_output_qs);
|
||||
@ -1250,24 +1254,31 @@ int qdio_allocate(struct ccw_device *cdev, unsigned int no_input_qs,
|
||||
*/
|
||||
irq_ptr->chsc_page = get_zeroed_page(GFP_KERNEL);
|
||||
if (!irq_ptr->chsc_page)
|
||||
goto out_rel;
|
||||
goto err_chsc;
|
||||
|
||||
/* qdr is used in ccw1.cda which is u32 */
|
||||
irq_ptr->qdr = (struct qdr *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
|
||||
if (!irq_ptr->qdr)
|
||||
goto out_rel;
|
||||
goto err_qdr;
|
||||
|
||||
if (qdio_allocate_qs(irq_ptr, no_input_qs, no_output_qs))
|
||||
goto out_rel;
|
||||
rc = qdio_allocate_qs(irq_ptr, no_input_qs, no_output_qs);
|
||||
if (rc)
|
||||
goto err_queues;
|
||||
|
||||
INIT_LIST_HEAD(&irq_ptr->entry);
|
||||
cdev->private->qdio_data = irq_ptr;
|
||||
qdio_set_state(irq_ptr, QDIO_IRQ_STATE_INACTIVE);
|
||||
return 0;
|
||||
out_rel:
|
||||
qdio_release_memory(irq_ptr);
|
||||
out_err:
|
||||
return -ENOMEM;
|
||||
|
||||
err_queues:
|
||||
qdio_free_queues(irq_ptr);
|
||||
free_page((unsigned long) irq_ptr->qdr);
|
||||
err_qdr:
|
||||
free_page(irq_ptr->chsc_page);
|
||||
err_chsc:
|
||||
err_dbf:
|
||||
free_page((unsigned long) irq_ptr);
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qdio_allocate);
|
||||
|
||||
|
@ -347,7 +347,7 @@ void qdio_setup_ssqd_info(struct qdio_irq *irq_ptr)
|
||||
DBF_EVENT("3:%4x qib:%4x", irq_ptr->ssqd_desc.qdioac3, irq_ptr->qib.ac);
|
||||
}
|
||||
|
||||
void qdio_release_memory(struct qdio_irq *irq_ptr)
|
||||
void qdio_free_queues(struct qdio_irq *irq_ptr)
|
||||
{
|
||||
struct qdio_q *q;
|
||||
int i;
|
||||
@ -383,9 +383,6 @@ void qdio_release_memory(struct qdio_irq *irq_ptr)
|
||||
kmem_cache_free(qdio_q_cache, q);
|
||||
}
|
||||
}
|
||||
free_page((unsigned long) irq_ptr->qdr);
|
||||
free_page(irq_ptr->chsc_page);
|
||||
free_page((unsigned long) irq_ptr);
|
||||
}
|
||||
|
||||
static void __qdio_allocate_fill_qdr(struct qdio_irq *irq_ptr,
|
||||
|
Loading…
Reference in New Issue
Block a user