]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blobdiff - src/patches/suse-2.6.27.31/patches.drivers/ehca-rejecting-dynamic-mem-add-remove.patch
Move xen patchset to new version's subdir.
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.drivers / ehca-rejecting-dynamic-mem-add-remove.patch
diff --git a/src/patches/suse-2.6.27.31/patches.drivers/ehca-rejecting-dynamic-mem-add-remove.patch b/src/patches/suse-2.6.27.31/patches.drivers/ehca-rejecting-dynamic-mem-add-remove.patch
new file mode 100644 (file)
index 0000000..2a3f731
--- /dev/null
@@ -0,0 +1,101 @@
+Subject: [PATCH]IB/ehca:reject dynamic memory add/remove
+From: Stefan Roscher <ossrosch@linux.vnet.ibm.com>
+References: 434651 - LTC48744
+
+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 memory regions already occupied and being
+used by InfiniBand applications.
+The solution 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.
+
+Signed-off-by: Stefan Roscher <stefan.roscher@de.ibm.com>
+Signed-off-by: Olaf Hering <olh@suse.de>
+
+---
+ drivers/infiniband/hw/ehca/ehca_main.c |   46 +++++++++++++++++++++++++++++++++
+ 1 file changed, 46 insertions(+)
+
+--- a/drivers/infiniband/hw/ehca/ehca_main.c
++++ b/drivers/infiniband/hw/ehca/ehca_main.c
+@@ -44,6 +44,8 @@
+ #include <linux/slab.h>
+ #endif
++#include <linux/notifier.h>
++#include <linux/memory.h>
+ #include "ehca_classes.h"
+ #include "ehca_iverbs.h"
+ #include "ehca_mrmw.h"
+@@ -965,6 +967,39 @@ void ehca_poll_eqs(unsigned long data)
+       spin_unlock(&shca_list_lock);
+ }
++static int ehca_mem_notifier(struct notifier_block *nb,
++                             unsigned long action, void *data)
++{
++      static unsigned long ehca_dmem_warn_time;
++
++      switch (action) {
++      case MEM_CANCEL_OFFLINE:
++      case MEM_CANCEL_ONLINE:
++      case MEM_ONLINE:
++      case MEM_OFFLINE:
++              return NOTIFY_OK;
++      case MEM_GOING_ONLINE:
++      case MEM_GOING_OFFLINE:
++              /* only ok if no hca is attached to the lpar */
++              spin_lock(&shca_list_lock);
++              if (list_empty(&shca_list)) {
++                      spin_unlock(&shca_list_lock);
++                      return NOTIFY_OK;
++              } else {
++                      spin_unlock(&shca_list_lock);
++                      if (printk_timed_ratelimit(&ehca_dmem_warn_time,
++                                                 30 * 1000))
++                              ehca_gen_err("DMEM operations are not allowed in conjunction with eHCA");
++                      return NOTIFY_BAD;
++              }
++      }
++      return NOTIFY_OK;
++}
++
++static struct notifier_block ehca_mem_nb = {
++      .notifier_call = ehca_mem_notifier,
++};
++
+ static int __init ehca_module_init(void)
+ {
+       int ret;
+@@ -992,6 +1027,12 @@ static int __init ehca_module_init(void)
+               goto module_init2;
+       }
++      ret = register_memory_notifier(&ehca_mem_nb);
++      if (ret) {
++              ehca_gen_err("Failed registering memory add/remove notifier");
++              goto module_init3;
++      }
++
+       if (ehca_poll_all_eqs != 1) {
+               ehca_gen_err("WARNING!!!");
+               ehca_gen_err("It is possible to lose interrupts.");
+@@ -1004,6 +1045,9 @@ static int __init ehca_module_init(void)
+       return 0;
++module_init3:
++      ibmebus_unregister_driver(&ehca_driver);
++
+ module_init2:
+       ehca_destroy_slab_caches();
+@@ -1019,6 +1063,8 @@ static void __exit ehca_module_exit(void
+       ibmebus_unregister_driver(&ehca_driver);
++      unregister_memory_notifier(&ehca_mem_nb);
++
+       ehca_destroy_slab_caches();
+       ehca_destroy_comp_pool();