aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ehea/ehea_main.c
diff options
context:
space:
mode:
authorThomas Klein <tklein@de.ibm.com>2010-04-20 19:11:31 -0400
committerDavid S. Miller <davem@davemloft.net>2010-04-22 01:32:44 -0400
commita7c561f2e32f98b477f5fe670b3f294be6b1eae2 (patch)
tree8ce32aacea816de1dbbd9e4bc9ce3460ba638c03 /drivers/net/ehea/ehea_main.c
parentea96ceac80cc82cb1c54a37bb8aaf4e695e87d0a (diff)
ehea: fix possible DLPAR/mem deadlock
Force serialization of userspace-triggered DLPAR/mem operations Signed-off-by: Thomas Klein <tklein@de.ibm.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/ehea/ehea_main.c')
-rw-r--r--drivers/net/ehea/ehea_main.c19
1 files changed, 14 insertions, 5 deletions
diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c
index c35d1e3631d1..39774817c3eb 100644
--- a/drivers/net/ehea/ehea_main.c
+++ b/drivers/net/ehea/ehea_main.c
@@ -2889,7 +2889,6 @@ static void ehea_rereg_mrs(struct work_struct *work)
2889 int ret, i; 2889 int ret, i;
2890 struct ehea_adapter *adapter; 2890 struct ehea_adapter *adapter;
2891 2891
2892 mutex_lock(&dlpar_mem_lock);
2893 ehea_info("LPAR memory changed - re-initializing driver"); 2892 ehea_info("LPAR memory changed - re-initializing driver");
2894 2893
2895 list_for_each_entry(adapter, &adapter_list, list) 2894 list_for_each_entry(adapter, &adapter_list, list)
@@ -2959,7 +2958,6 @@ static void ehea_rereg_mrs(struct work_struct *work)
2959 } 2958 }
2960 ehea_info("re-initializing driver complete"); 2959 ehea_info("re-initializing driver complete");
2961out: 2960out:
2962 mutex_unlock(&dlpar_mem_lock);
2963 return; 2961 return;
2964} 2962}
2965 2963
@@ -3542,7 +3540,14 @@ void ehea_crash_handler(void)
3542static int ehea_mem_notifier(struct notifier_block *nb, 3540static int ehea_mem_notifier(struct notifier_block *nb,
3543 unsigned long action, void *data) 3541 unsigned long action, void *data)
3544{ 3542{
3543 int ret = NOTIFY_BAD;
3545 struct memory_notify *arg = data; 3544 struct memory_notify *arg = data;
3545
3546 if (!mutex_trylock(&dlpar_mem_lock)) {
3547 ehea_info("ehea_mem_notifier must not be called parallelized");
3548 goto out;
3549 }
3550
3546 switch (action) { 3551 switch (action) {
3547 case MEM_CANCEL_OFFLINE: 3552 case MEM_CANCEL_OFFLINE:
3548 ehea_info("memory offlining canceled"); 3553 ehea_info("memory offlining canceled");
@@ -3551,14 +3556,14 @@ static int ehea_mem_notifier(struct notifier_block *nb,
3551 ehea_info("memory is going online"); 3556 ehea_info("memory is going online");
3552 set_bit(__EHEA_STOP_XFER, &ehea_driver_flags); 3557 set_bit(__EHEA_STOP_XFER, &ehea_driver_flags);
3553 if (ehea_add_sect_bmap(arg->start_pfn, arg->nr_pages)) 3558 if (ehea_add_sect_bmap(arg->start_pfn, arg->nr_pages))
3554 return NOTIFY_BAD; 3559 goto out_unlock;
3555 ehea_rereg_mrs(NULL); 3560 ehea_rereg_mrs(NULL);
3556 break; 3561 break;
3557 case MEM_GOING_OFFLINE: 3562 case MEM_GOING_OFFLINE:
3558 ehea_info("memory is going offline"); 3563 ehea_info("memory is going offline");
3559 set_bit(__EHEA_STOP_XFER, &ehea_driver_flags); 3564 set_bit(__EHEA_STOP_XFER, &ehea_driver_flags);
3560 if (ehea_rem_sect_bmap(arg->start_pfn, arg->nr_pages)) 3565 if (ehea_rem_sect_bmap(arg->start_pfn, arg->nr_pages))
3561 return NOTIFY_BAD; 3566 goto out_unlock;
3562 ehea_rereg_mrs(NULL); 3567 ehea_rereg_mrs(NULL);
3563 break; 3568 break;
3564 default: 3569 default:
@@ -3566,8 +3571,12 @@ static int ehea_mem_notifier(struct notifier_block *nb,
3566 } 3571 }
3567 3572
3568 ehea_update_firmware_handles(); 3573 ehea_update_firmware_handles();
3574 ret = NOTIFY_OK;
3569 3575
3570 return NOTIFY_OK; 3576out_unlock:
3577 mutex_unlock(&dlpar_mem_lock);
3578out:
3579 return ret;
3571} 3580}
3572 3581
3573static struct notifier_block ehea_mem_nb = { 3582static struct notifier_block ehea_mem_nb = {