aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/infiniband/hw/ehca
diff options
context:
space:
mode:
authorStefan Roscher <ossrosch@linux.vnet.ibm.com>2008-10-22 18:54:38 -0400
committerRoland Dreier <rolandd@cisco.com>2008-10-22 18:54:38 -0400
commit263c24a2bbbaca75805ed231e8346d86410af9d0 (patch)
treea4de046c1f94f381d1ab241b4a719a25ea58ec66 /drivers/infiniband/hw/ehca
parent19f4282149147b4a3e8c670373dc73ddd5d5facc (diff)
IB/ehca: Reject dynamic memory add/remove when ehca adapter is present
Since the ehca device driver does not support dynamic memory add and remove operations, the driver must explicitly reject such requests in order to prevent unpredictable behaviors related to existing memory regions that cover all of memory being used by InfiniBand protocols in the kernel. The solution (for now at least) is to add a memory notifier to the ehca device driver and if a request for dynamic memory add or remove comes in, ehca will always reject it. The user can add or remove memory by hot-removing the ehca adapter, performing the memory operation, and then hot-adding the ehca adapter back. Signed-off-by: Stefan Roscher <stefan.roscher@de.ibm.com> Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband/hw/ehca')
-rw-r--r--drivers/infiniband/hw/ehca/ehca_main.c48
1 files changed, 48 insertions, 0 deletions
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c
index 086959a0cbee..bb02a86aa526 100644
--- a/drivers/infiniband/hw/ehca/ehca_main.c
+++ b/drivers/infiniband/hw/ehca/ehca_main.c
@@ -44,6 +44,8 @@
44#include <linux/slab.h> 44#include <linux/slab.h>
45#endif 45#endif
46 46
47#include <linux/notifier.h>
48#include <linux/memory.h>
47#include "ehca_classes.h" 49#include "ehca_classes.h"
48#include "ehca_iverbs.h" 50#include "ehca_iverbs.h"
49#include "ehca_mrmw.h" 51#include "ehca_mrmw.h"
@@ -969,6 +971,41 @@ void ehca_poll_eqs(unsigned long data)
969 spin_unlock(&shca_list_lock); 971 spin_unlock(&shca_list_lock);
970} 972}
971 973
974static int ehca_mem_notifier(struct notifier_block *nb,
975 unsigned long action, void *data)
976{
977 static unsigned long ehca_dmem_warn_time;
978
979 switch (action) {
980 case MEM_CANCEL_OFFLINE:
981 case MEM_CANCEL_ONLINE:
982 case MEM_ONLINE:
983 case MEM_OFFLINE:
984 return NOTIFY_OK;
985 case MEM_GOING_ONLINE:
986 case MEM_GOING_OFFLINE:
987 /* only ok if no hca is attached to the lpar */
988 spin_lock(&shca_list_lock);
989 if (list_empty(&shca_list)) {
990 spin_unlock(&shca_list_lock);
991 return NOTIFY_OK;
992 } else {
993 spin_unlock(&shca_list_lock);
994 if (printk_timed_ratelimit(&ehca_dmem_warn_time,
995 30 * 1000))
996 ehca_gen_err("DMEM operations are not allowed"
997 "as long as an ehca adapter is"
998 "attached to the LPAR");
999 return NOTIFY_BAD;
1000 }
1001 }
1002 return NOTIFY_OK;
1003}
1004
1005static struct notifier_block ehca_mem_nb = {
1006 .notifier_call = ehca_mem_notifier,
1007};
1008
972static int __init ehca_module_init(void) 1009static int __init ehca_module_init(void)
973{ 1010{
974 int ret; 1011 int ret;
@@ -996,6 +1033,12 @@ static int __init ehca_module_init(void)
996 goto module_init2; 1033 goto module_init2;
997 } 1034 }
998 1035
1036 ret = register_memory_notifier(&ehca_mem_nb);
1037 if (ret) {
1038 ehca_gen_err("Failed registering memory add/remove notifier");
1039 goto module_init3;
1040 }
1041
999 if (ehca_poll_all_eqs != 1) { 1042 if (ehca_poll_all_eqs != 1) {
1000 ehca_gen_err("WARNING!!!"); 1043 ehca_gen_err("WARNING!!!");
1001 ehca_gen_err("It is possible to lose interrupts."); 1044 ehca_gen_err("It is possible to lose interrupts.");
@@ -1008,6 +1051,9 @@ static int __init ehca_module_init(void)
1008 1051
1009 return 0; 1052 return 0;
1010 1053
1054module_init3:
1055 ibmebus_unregister_driver(&ehca_driver);
1056
1011module_init2: 1057module_init2:
1012 ehca_destroy_slab_caches(); 1058 ehca_destroy_slab_caches();
1013 1059
@@ -1023,6 +1069,8 @@ static void __exit ehca_module_exit(void)
1023 1069
1024 ibmebus_unregister_driver(&ehca_driver); 1070 ibmebus_unregister_driver(&ehca_driver);
1025 1071
1072 unregister_memory_notifier(&ehca_mem_nb);
1073
1026 ehca_destroy_slab_caches(); 1074 ehca_destroy_slab_caches();
1027 1075
1028 ehca_destroy_comp_pool(); 1076 ehca_destroy_comp_pool();