]> git.ipfire.org Git - ipfire-2.x.git/blob - src/patches/suse-2.6.27.31/patches.drivers/ehca-rejecting-dynamic-mem-add-remove.patch
Add a patch to fix Intel E100 wake-on-lan problems.
[ipfire-2.x.git] / src / patches / suse-2.6.27.31 / patches.drivers / ehca-rejecting-dynamic-mem-add-remove.patch
1 Subject: [PATCH]IB/ehca:reject dynamic memory add/remove
2 From: Stefan Roscher <ossrosch@linux.vnet.ibm.com>
3 References: 434651 - LTC48744
4
5 Since the ehca device driver does not support dynamic memory add and remove
6 operations, the driver must explicitly reject such requests in order to prevent
7 unpredictable behaviors related to memory regions already occupied and being
8 used by InfiniBand applications.
9 The solution is to add a memory notifier to the ehca device driver and if a request
10 for dynamic memory add or remove comes in, ehca will always reject it.
11
12 Signed-off-by: Stefan Roscher <stefan.roscher@de.ibm.com>
13 Signed-off-by: Olaf Hering <olh@suse.de>
14
15 ---
16 drivers/infiniband/hw/ehca/ehca_main.c | 46 +++++++++++++++++++++++++++++++++
17 1 file changed, 46 insertions(+)
18
19 --- a/drivers/infiniband/hw/ehca/ehca_main.c
20 +++ b/drivers/infiniband/hw/ehca/ehca_main.c
21 @@ -44,6 +44,8 @@
22 #include <linux/slab.h>
23 #endif
24
25 +#include <linux/notifier.h>
26 +#include <linux/memory.h>
27 #include "ehca_classes.h"
28 #include "ehca_iverbs.h"
29 #include "ehca_mrmw.h"
30 @@ -965,6 +967,39 @@ void ehca_poll_eqs(unsigned long data)
31 spin_unlock(&shca_list_lock);
32 }
33
34 +static int ehca_mem_notifier(struct notifier_block *nb,
35 + unsigned long action, void *data)
36 +{
37 + static unsigned long ehca_dmem_warn_time;
38 +
39 + switch (action) {
40 + case MEM_CANCEL_OFFLINE:
41 + case MEM_CANCEL_ONLINE:
42 + case MEM_ONLINE:
43 + case MEM_OFFLINE:
44 + return NOTIFY_OK;
45 + case MEM_GOING_ONLINE:
46 + case MEM_GOING_OFFLINE:
47 + /* only ok if no hca is attached to the lpar */
48 + spin_lock(&shca_list_lock);
49 + if (list_empty(&shca_list)) {
50 + spin_unlock(&shca_list_lock);
51 + return NOTIFY_OK;
52 + } else {
53 + spin_unlock(&shca_list_lock);
54 + if (printk_timed_ratelimit(&ehca_dmem_warn_time,
55 + 30 * 1000))
56 + ehca_gen_err("DMEM operations are not allowed in conjunction with eHCA");
57 + return NOTIFY_BAD;
58 + }
59 + }
60 + return NOTIFY_OK;
61 +}
62 +
63 +static struct notifier_block ehca_mem_nb = {
64 + .notifier_call = ehca_mem_notifier,
65 +};
66 +
67 static int __init ehca_module_init(void)
68 {
69 int ret;
70 @@ -992,6 +1027,12 @@ static int __init ehca_module_init(void)
71 goto module_init2;
72 }
73
74 + ret = register_memory_notifier(&ehca_mem_nb);
75 + if (ret) {
76 + ehca_gen_err("Failed registering memory add/remove notifier");
77 + goto module_init3;
78 + }
79 +
80 if (ehca_poll_all_eqs != 1) {
81 ehca_gen_err("WARNING!!!");
82 ehca_gen_err("It is possible to lose interrupts.");
83 @@ -1004,6 +1045,9 @@ static int __init ehca_module_init(void)
84
85 return 0;
86
87 +module_init3:
88 + ibmebus_unregister_driver(&ehca_driver);
89 +
90 module_init2:
91 ehca_destroy_slab_caches();
92
93 @@ -1019,6 +1063,8 @@ static void __exit ehca_module_exit(void
94
95 ibmebus_unregister_driver(&ehca_driver);
96
97 + unregister_memory_notifier(&ehca_mem_nb);
98 +
99 ehca_destroy_slab_caches();
100
101 ehca_destroy_comp_pool();