IB/hfi1: Fix sleep inside atomic issue in init_asic_data
The critical section should protect only the list traversal and dd->asic_data modification, not the memory allocation. The fix pulls the allocation out of the critical section. Reviewed-by: Dennis Dalessandro <dennis.dalessandro@intel.com> Reviewed-by: Sebastian Sanchez <sebastian.sanchez@intel.com> Reviewed-by: Dean Luick <dean.luick@intel.com> Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com> Signed-off-by: Dennis Dalessandro <dennis.dalessandro@intel.com> Signed-off-by: Mike Marciniszyn <mike.marciniszyn@intel.com> Signed-off-by: Doug Ledford <dledford@redhat.com>
This commit is contained in:
parent
896ce45da2
commit
98f179a5ea
|
@ -14113,8 +14113,14 @@ static int init_asic_data(struct hfi1_devdata *dd)
|
|||
{
|
||||
unsigned long flags;
|
||||
struct hfi1_devdata *tmp, *peer = NULL;
|
||||
struct hfi1_asic_data *asic_data;
|
||||
int ret = 0;
|
||||
|
||||
/* pre-allocate the asic structure in case we are the first device */
|
||||
asic_data = kzalloc(sizeof(*dd->asic_data), GFP_KERNEL);
|
||||
if (!asic_data)
|
||||
return -ENOMEM;
|
||||
|
||||
spin_lock_irqsave(&hfi1_devs_lock, flags);
|
||||
/* Find our peer device */
|
||||
list_for_each_entry(tmp, &hfi1_dev_list, list) {
|
||||
|
@ -14126,18 +14132,14 @@ static int init_asic_data(struct hfi1_devdata *dd)
|
|||
}
|
||||
|
||||
if (peer) {
|
||||
/* use already allocated structure */
|
||||
dd->asic_data = peer->asic_data;
|
||||
kfree(asic_data);
|
||||
} else {
|
||||
dd->asic_data = kzalloc(sizeof(*dd->asic_data), GFP_KERNEL);
|
||||
if (!dd->asic_data) {
|
||||
ret = -ENOMEM;
|
||||
goto done;
|
||||
}
|
||||
dd->asic_data = asic_data;
|
||||
mutex_init(&dd->asic_data->asic_resource_mutex);
|
||||
}
|
||||
dd->asic_data->dds[dd->hfi1_id] = dd; /* self back-pointer */
|
||||
|
||||
done:
|
||||
spin_unlock_irqrestore(&hfi1_devs_lock, flags);
|
||||
return ret;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue