+++ /dev/null
-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();