aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/infiniband/core/cache.c2
-rw-r--r--drivers/infiniband/core/cm.c7
-rw-r--r--drivers/infiniband/core/cma.c7
-rw-r--r--drivers/infiniband/core/device.c53
-rw-r--r--drivers/infiniband/core/mad.c2
-rw-r--r--drivers/infiniband/core/multicast.c7
-rw-r--r--drivers/infiniband/core/sa_query.c6
-rw-r--r--drivers/infiniband/core/ucm.c6
-rw-r--r--drivers/infiniband/core/user_mad.c6
-rw-r--r--drivers/infiniband/core/uverbs_main.c6
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_main.c7
-rw-r--r--drivers/infiniband/ulp/srp/ib_srp.c6
-rw-r--r--drivers/infiniband/ulp/srpt/ib_srpt.c5
-rw-r--r--include/rdma/ib_verbs.h4
-rw-r--r--net/rds/ib.c5
-rw-r--r--net/rds/iw.c5
16 files changed, 82 insertions, 52 deletions
diff --git a/drivers/infiniband/core/cache.c b/drivers/infiniband/core/cache.c
index 871da832d016..c93af66cc091 100644
--- a/drivers/infiniband/core/cache.c
+++ b/drivers/infiniband/core/cache.c
@@ -394,7 +394,7 @@ err:
394 kfree(device->cache.lmc_cache); 394 kfree(device->cache.lmc_cache);
395} 395}
396 396
397static void ib_cache_cleanup_one(struct ib_device *device) 397static void ib_cache_cleanup_one(struct ib_device *device, void *client_data)
398{ 398{
399 int p; 399 int p;
400 400
diff --git a/drivers/infiniband/core/cm.c b/drivers/infiniband/core/cm.c
index 3a972ebf3c0d..82d5c4362aa8 100644
--- a/drivers/infiniband/core/cm.c
+++ b/drivers/infiniband/core/cm.c
@@ -58,7 +58,7 @@ MODULE_DESCRIPTION("InfiniBand CM");
58MODULE_LICENSE("Dual BSD/GPL"); 58MODULE_LICENSE("Dual BSD/GPL");
59 59
60static void cm_add_one(struct ib_device *device); 60static void cm_add_one(struct ib_device *device);
61static void cm_remove_one(struct ib_device *device); 61static void cm_remove_one(struct ib_device *device, void *client_data);
62 62
63static struct ib_client cm_client = { 63static struct ib_client cm_client = {
64 .name = "cm", 64 .name = "cm",
@@ -3886,9 +3886,9 @@ free:
3886 kfree(cm_dev); 3886 kfree(cm_dev);
3887} 3887}
3888 3888
3889static void cm_remove_one(struct ib_device *ib_device) 3889static void cm_remove_one(struct ib_device *ib_device, void *client_data)
3890{ 3890{
3891 struct cm_device *cm_dev; 3891 struct cm_device *cm_dev = client_data;
3892 struct cm_port *port; 3892 struct cm_port *port;
3893 struct ib_port_modify port_modify = { 3893 struct ib_port_modify port_modify = {
3894 .clr_port_cap_mask = IB_PORT_CM_SUP 3894 .clr_port_cap_mask = IB_PORT_CM_SUP
@@ -3896,7 +3896,6 @@ static void cm_remove_one(struct ib_device *ib_device)
3896 unsigned long flags; 3896 unsigned long flags;
3897 int i; 3897 int i;
3898 3898
3899 cm_dev = ib_get_client_data(ib_device, &cm_client);
3900 if (!cm_dev) 3899 if (!cm_dev)
3901 return; 3900 return;
3902 3901
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index 4e72e4c16cfe..9664131c4eeb 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -94,7 +94,7 @@ const char *rdma_event_msg(enum rdma_cm_event_type event)
94EXPORT_SYMBOL(rdma_event_msg); 94EXPORT_SYMBOL(rdma_event_msg);
95 95
96static void cma_add_one(struct ib_device *device); 96static void cma_add_one(struct ib_device *device);
97static void cma_remove_one(struct ib_device *device); 97static void cma_remove_one(struct ib_device *device, void *client_data);
98 98
99static struct ib_client cma_client = { 99static struct ib_client cma_client = {
100 .name = "cma", 100 .name = "cma",
@@ -3554,11 +3554,10 @@ static void cma_process_remove(struct cma_device *cma_dev)
3554 wait_for_completion(&cma_dev->comp); 3554 wait_for_completion(&cma_dev->comp);
3555} 3555}
3556 3556
3557static void cma_remove_one(struct ib_device *device) 3557static void cma_remove_one(struct ib_device *device, void *client_data)
3558{ 3558{
3559 struct cma_device *cma_dev; 3559 struct cma_device *cma_dev = client_data;
3560 3560
3561 cma_dev = ib_get_client_data(device, &cma_client);
3562 if (!cma_dev) 3561 if (!cma_dev)
3563 return; 3562 return;
3564 3563
diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c
index 0c8fa781538b..ce317e623862 100644
--- a/drivers/infiniband/core/device.c
+++ b/drivers/infiniband/core/device.c
@@ -50,6 +50,9 @@ struct ib_client_data {
50 struct list_head list; 50 struct list_head list;
51 struct ib_client *client; 51 struct ib_client *client;
52 void * data; 52 void * data;
53 /* The device or client is going down. Do not call client or device
54 * callbacks other than remove(). */
55 bool going_down;
53}; 56};
54 57
55struct workqueue_struct *ib_wq; 58struct workqueue_struct *ib_wq;
@@ -69,6 +72,8 @@ static LIST_HEAD(client_list);
69 * to the lists must be done with a write lock. A special case is when the 72 * to the lists must be done with a write lock. A special case is when the
70 * device_mutex is locked. In this case locking the lists for read access is 73 * device_mutex is locked. In this case locking the lists for read access is
71 * not necessary as the device_mutex implies it. 74 * not necessary as the device_mutex implies it.
75 *
76 * lists_rwsem also protects access to the client data list.
72 */ 77 */
73static DEFINE_MUTEX(device_mutex); 78static DEFINE_MUTEX(device_mutex);
74static DECLARE_RWSEM(lists_rwsem); 79static DECLARE_RWSEM(lists_rwsem);
@@ -210,10 +215,13 @@ static int add_client_context(struct ib_device *device, struct ib_client *client
210 215
211 context->client = client; 216 context->client = client;
212 context->data = NULL; 217 context->data = NULL;
218 context->going_down = false;
213 219
220 down_write(&lists_rwsem);
214 spin_lock_irqsave(&device->client_data_lock, flags); 221 spin_lock_irqsave(&device->client_data_lock, flags);
215 list_add(&context->list, &device->client_data_list); 222 list_add(&context->list, &device->client_data_list);
216 spin_unlock_irqrestore(&device->client_data_lock, flags); 223 spin_unlock_irqrestore(&device->client_data_lock, flags);
224 up_write(&lists_rwsem);
217 225
218 return 0; 226 return 0;
219} 227}
@@ -339,7 +347,6 @@ EXPORT_SYMBOL(ib_register_device);
339 */ 347 */
340void ib_unregister_device(struct ib_device *device) 348void ib_unregister_device(struct ib_device *device)
341{ 349{
342 struct ib_client *client;
343 struct ib_client_data *context, *tmp; 350 struct ib_client_data *context, *tmp;
344 unsigned long flags; 351 unsigned long flags;
345 352
@@ -347,20 +354,29 @@ void ib_unregister_device(struct ib_device *device)
347 354
348 down_write(&lists_rwsem); 355 down_write(&lists_rwsem);
349 list_del(&device->core_list); 356 list_del(&device->core_list);
350 up_write(&lists_rwsem); 357 spin_lock_irqsave(&device->client_data_lock, flags);
358 list_for_each_entry_safe(context, tmp, &device->client_data_list, list)
359 context->going_down = true;
360 spin_unlock_irqrestore(&device->client_data_lock, flags);
361 downgrade_write(&lists_rwsem);
351 362
352 list_for_each_entry_reverse(client, &client_list, list) 363 list_for_each_entry_safe(context, tmp, &device->client_data_list,
353 if (client->remove) 364 list) {
354 client->remove(device); 365 if (context->client->remove)
366 context->client->remove(device, context->data);
367 }
368 up_read(&lists_rwsem);
355 369
356 mutex_unlock(&device_mutex); 370 mutex_unlock(&device_mutex);
357 371
358 ib_device_unregister_sysfs(device); 372 ib_device_unregister_sysfs(device);
359 373
374 down_write(&lists_rwsem);
360 spin_lock_irqsave(&device->client_data_lock, flags); 375 spin_lock_irqsave(&device->client_data_lock, flags);
361 list_for_each_entry_safe(context, tmp, &device->client_data_list, list) 376 list_for_each_entry_safe(context, tmp, &device->client_data_list, list)
362 kfree(context); 377 kfree(context);
363 spin_unlock_irqrestore(&device->client_data_lock, flags); 378 spin_unlock_irqrestore(&device->client_data_lock, flags);
379 up_write(&lists_rwsem);
364 380
365 device->reg_state = IB_DEV_UNREGISTERED; 381 device->reg_state = IB_DEV_UNREGISTERED;
366} 382}
@@ -420,16 +436,35 @@ void ib_unregister_client(struct ib_client *client)
420 up_write(&lists_rwsem); 436 up_write(&lists_rwsem);
421 437
422 list_for_each_entry(device, &device_list, core_list) { 438 list_for_each_entry(device, &device_list, core_list) {
423 if (client->remove) 439 struct ib_client_data *found_context = NULL;
424 client->remove(device);
425 440
441 down_write(&lists_rwsem);
426 spin_lock_irqsave(&device->client_data_lock, flags); 442 spin_lock_irqsave(&device->client_data_lock, flags);
427 list_for_each_entry_safe(context, tmp, &device->client_data_list, list) 443 list_for_each_entry_safe(context, tmp, &device->client_data_list, list)
428 if (context->client == client) { 444 if (context->client == client) {
429 list_del(&context->list); 445 context->going_down = true;
430 kfree(context); 446 found_context = context;
447 break;
431 } 448 }
432 spin_unlock_irqrestore(&device->client_data_lock, flags); 449 spin_unlock_irqrestore(&device->client_data_lock, flags);
450 up_write(&lists_rwsem);
451
452 if (client->remove)
453 client->remove(device, found_context ?
454 found_context->data : NULL);
455
456 if (!found_context) {
457 pr_warn("No client context found for %s/%s\n",
458 device->name, client->name);
459 continue;
460 }
461
462 down_write(&lists_rwsem);
463 spin_lock_irqsave(&device->client_data_lock, flags);
464 list_del(&found_context->list);
465 kfree(found_context);
466 spin_unlock_irqrestore(&device->client_data_lock, flags);
467 up_write(&lists_rwsem);
433 } 468 }
434 469
435 mutex_unlock(&device_mutex); 470 mutex_unlock(&device_mutex);
diff --git a/drivers/infiniband/core/mad.c b/drivers/infiniband/core/mad.c
index 786fc51bf04b..66b4b3eb8f67 100644
--- a/drivers/infiniband/core/mad.c
+++ b/drivers/infiniband/core/mad.c
@@ -3335,7 +3335,7 @@ error:
3335 } 3335 }
3336} 3336}
3337 3337
3338static void ib_mad_remove_device(struct ib_device *device) 3338static void ib_mad_remove_device(struct ib_device *device, void *client_data)
3339{ 3339{
3340 int i; 3340 int i;
3341 3341
diff --git a/drivers/infiniband/core/multicast.c b/drivers/infiniband/core/multicast.c
index 2cb865c7ce7a..d38d8b2b2979 100644
--- a/drivers/infiniband/core/multicast.c
+++ b/drivers/infiniband/core/multicast.c
@@ -43,7 +43,7 @@
43#include "sa.h" 43#include "sa.h"
44 44
45static void mcast_add_one(struct ib_device *device); 45static void mcast_add_one(struct ib_device *device);
46static void mcast_remove_one(struct ib_device *device); 46static void mcast_remove_one(struct ib_device *device, void *client_data);
47 47
48static struct ib_client mcast_client = { 48static struct ib_client mcast_client = {
49 .name = "ib_multicast", 49 .name = "ib_multicast",
@@ -840,13 +840,12 @@ static void mcast_add_one(struct ib_device *device)
840 ib_register_event_handler(&dev->event_handler); 840 ib_register_event_handler(&dev->event_handler);
841} 841}
842 842
843static void mcast_remove_one(struct ib_device *device) 843static void mcast_remove_one(struct ib_device *device, void *client_data)
844{ 844{
845 struct mcast_device *dev; 845 struct mcast_device *dev = client_data;
846 struct mcast_port *port; 846 struct mcast_port *port;
847 int i; 847 int i;
848 848
849 dev = ib_get_client_data(device, &mcast_client);
850 if (!dev) 849 if (!dev)
851 return; 850 return;
852 851
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c
index ca919f429666..d40be3673b79 100644
--- a/drivers/infiniband/core/sa_query.c
+++ b/drivers/infiniband/core/sa_query.c
@@ -107,7 +107,7 @@ struct ib_sa_mcmember_query {
107}; 107};
108 108
109static void ib_sa_add_one(struct ib_device *device); 109static void ib_sa_add_one(struct ib_device *device);
110static void ib_sa_remove_one(struct ib_device *device); 110static void ib_sa_remove_one(struct ib_device *device, void *client_data);
111 111
112static struct ib_client sa_client = { 112static struct ib_client sa_client = {
113 .name = "sa", 113 .name = "sa",
@@ -1221,9 +1221,9 @@ free:
1221 return; 1221 return;
1222} 1222}
1223 1223
1224static void ib_sa_remove_one(struct ib_device *device) 1224static void ib_sa_remove_one(struct ib_device *device, void *client_data)
1225{ 1225{
1226 struct ib_sa_device *sa_dev = ib_get_client_data(device, &sa_client); 1226 struct ib_sa_device *sa_dev = client_data;
1227 int i; 1227 int i;
1228 1228
1229 if (!sa_dev) 1229 if (!sa_dev)
diff --git a/drivers/infiniband/core/ucm.c b/drivers/infiniband/core/ucm.c
index 009481073644..8cde48b96f19 100644
--- a/drivers/infiniband/core/ucm.c
+++ b/drivers/infiniband/core/ucm.c
@@ -109,7 +109,7 @@ enum {
109#define IB_UCM_BASE_DEV MKDEV(IB_UCM_MAJOR, IB_UCM_BASE_MINOR) 109#define IB_UCM_BASE_DEV MKDEV(IB_UCM_MAJOR, IB_UCM_BASE_MINOR)
110 110
111static void ib_ucm_add_one(struct ib_device *device); 111static void ib_ucm_add_one(struct ib_device *device);
112static void ib_ucm_remove_one(struct ib_device *device); 112static void ib_ucm_remove_one(struct ib_device *device, void *client_data);
113 113
114static struct ib_client ucm_client = { 114static struct ib_client ucm_client = {
115 .name = "ucm", 115 .name = "ucm",
@@ -1310,9 +1310,9 @@ err:
1310 return; 1310 return;
1311} 1311}
1312 1312
1313static void ib_ucm_remove_one(struct ib_device *device) 1313static void ib_ucm_remove_one(struct ib_device *device, void *client_data)
1314{ 1314{
1315 struct ib_ucm_device *ucm_dev = ib_get_client_data(device, &ucm_client); 1315 struct ib_ucm_device *ucm_dev = client_data;
1316 1316
1317 if (!ucm_dev) 1317 if (!ucm_dev)
1318 return; 1318 return;
diff --git a/drivers/infiniband/core/user_mad.c b/drivers/infiniband/core/user_mad.c
index 35567fffaa4e..57f281f8d686 100644
--- a/drivers/infiniband/core/user_mad.c
+++ b/drivers/infiniband/core/user_mad.c
@@ -133,7 +133,7 @@ static DEFINE_SPINLOCK(port_lock);
133static DECLARE_BITMAP(dev_map, IB_UMAD_MAX_PORTS); 133static DECLARE_BITMAP(dev_map, IB_UMAD_MAX_PORTS);
134 134
135static void ib_umad_add_one(struct ib_device *device); 135static void ib_umad_add_one(struct ib_device *device);
136static void ib_umad_remove_one(struct ib_device *device); 136static void ib_umad_remove_one(struct ib_device *device, void *client_data);
137 137
138static void ib_umad_release_dev(struct kobject *kobj) 138static void ib_umad_release_dev(struct kobject *kobj)
139{ 139{
@@ -1322,9 +1322,9 @@ free:
1322 kobject_put(&umad_dev->kobj); 1322 kobject_put(&umad_dev->kobj);
1323} 1323}
1324 1324
1325static void ib_umad_remove_one(struct ib_device *device) 1325static void ib_umad_remove_one(struct ib_device *device, void *client_data)
1326{ 1326{
1327 struct ib_umad_device *umad_dev = ib_get_client_data(device, &umad_client); 1327 struct ib_umad_device *umad_dev = client_data;
1328 int i; 1328 int i;
1329 1329
1330 if (!umad_dev) 1330 if (!umad_dev)
diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c
index f6eef2da7097..46c92294afa5 100644
--- a/drivers/infiniband/core/uverbs_main.c
+++ b/drivers/infiniband/core/uverbs_main.c
@@ -128,7 +128,7 @@ static int (*uverbs_ex_cmd_table[])(struct ib_uverbs_file *file,
128}; 128};
129 129
130static void ib_uverbs_add_one(struct ib_device *device); 130static void ib_uverbs_add_one(struct ib_device *device);
131static void ib_uverbs_remove_one(struct ib_device *device); 131static void ib_uverbs_remove_one(struct ib_device *device, void *client_data);
132 132
133static void ib_uverbs_release_dev(struct kref *ref) 133static void ib_uverbs_release_dev(struct kref *ref)
134{ 134{
@@ -948,9 +948,9 @@ err:
948 return; 948 return;
949} 949}
950 950
951static void ib_uverbs_remove_one(struct ib_device *device) 951static void ib_uverbs_remove_one(struct ib_device *device, void *client_data)
952{ 952{
953 struct ib_uverbs_device *uverbs_dev = ib_get_client_data(device, &uverbs_client); 953 struct ib_uverbs_device *uverbs_dev = client_data;
954 954
955 if (!uverbs_dev) 955 if (!uverbs_dev)
956 return; 956 return;
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c
index b2943c84a5dd..cca1a0c91ec4 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_main.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c
@@ -89,7 +89,7 @@ struct workqueue_struct *ipoib_workqueue;
89struct ib_sa_client ipoib_sa_client; 89struct ib_sa_client ipoib_sa_client;
90 90
91static void ipoib_add_one(struct ib_device *device); 91static void ipoib_add_one(struct ib_device *device);
92static void ipoib_remove_one(struct ib_device *device); 92static void ipoib_remove_one(struct ib_device *device, void *client_data);
93static void ipoib_neigh_reclaim(struct rcu_head *rp); 93static void ipoib_neigh_reclaim(struct rcu_head *rp);
94 94
95static struct ib_client ipoib_client = { 95static struct ib_client ipoib_client = {
@@ -1715,12 +1715,11 @@ static void ipoib_add_one(struct ib_device *device)
1715 ib_set_client_data(device, &ipoib_client, dev_list); 1715 ib_set_client_data(device, &ipoib_client, dev_list);
1716} 1716}
1717 1717
1718static void ipoib_remove_one(struct ib_device *device) 1718static void ipoib_remove_one(struct ib_device *device, void *client_data)
1719{ 1719{
1720 struct ipoib_dev_priv *priv, *tmp; 1720 struct ipoib_dev_priv *priv, *tmp;
1721 struct list_head *dev_list; 1721 struct list_head *dev_list = client_data;
1722 1722
1723 dev_list = ib_get_client_data(device, &ipoib_client);
1724 if (!dev_list) 1723 if (!dev_list)
1725 return; 1724 return;
1726 1725
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c
index 31a20b462266..7755df444cfd 100644
--- a/drivers/infiniband/ulp/srp/ib_srp.c
+++ b/drivers/infiniband/ulp/srp/ib_srp.c
@@ -131,7 +131,7 @@ MODULE_PARM_DESC(ch_count,
131 "Number of RDMA channels to use for communication with an SRP target. Using more than one channel improves performance if the HCA supports multiple completion vectors. The default value is the minimum of four times the number of online CPU sockets and the number of completion vectors supported by the HCA."); 131 "Number of RDMA channels to use for communication with an SRP target. Using more than one channel improves performance if the HCA supports multiple completion vectors. The default value is the minimum of four times the number of online CPU sockets and the number of completion vectors supported by the HCA.");
132 132
133static void srp_add_one(struct ib_device *device); 133static void srp_add_one(struct ib_device *device);
134static void srp_remove_one(struct ib_device *device); 134static void srp_remove_one(struct ib_device *device, void *client_data);
135static void srp_recv_completion(struct ib_cq *cq, void *ch_ptr); 135static void srp_recv_completion(struct ib_cq *cq, void *ch_ptr);
136static void srp_send_completion(struct ib_cq *cq, void *ch_ptr); 136static void srp_send_completion(struct ib_cq *cq, void *ch_ptr);
137static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event); 137static int srp_cm_handler(struct ib_cm_id *cm_id, struct ib_cm_event *event);
@@ -3460,13 +3460,13 @@ free_attr:
3460 kfree(dev_attr); 3460 kfree(dev_attr);
3461} 3461}
3462 3462
3463static void srp_remove_one(struct ib_device *device) 3463static void srp_remove_one(struct ib_device *device, void *client_data)
3464{ 3464{
3465 struct srp_device *srp_dev; 3465 struct srp_device *srp_dev;
3466 struct srp_host *host, *tmp_host; 3466 struct srp_host *host, *tmp_host;
3467 struct srp_target_port *target; 3467 struct srp_target_port *target;
3468 3468
3469 srp_dev = ib_get_client_data(device, &srp_client); 3469 srp_dev = client_data;
3470 if (!srp_dev) 3470 if (!srp_dev)
3471 return; 3471 return;
3472 3472
diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c
index 60ff0a2390e5..4c59ceb40fff 100644
--- a/drivers/infiniband/ulp/srpt/ib_srpt.c
+++ b/drivers/infiniband/ulp/srpt/ib_srpt.c
@@ -3326,12 +3326,11 @@ err:
3326/** 3326/**
3327 * srpt_remove_one() - InfiniBand device removal callback function. 3327 * srpt_remove_one() - InfiniBand device removal callback function.
3328 */ 3328 */
3329static void srpt_remove_one(struct ib_device *device) 3329static void srpt_remove_one(struct ib_device *device, void *client_data)
3330{ 3330{
3331 struct srpt_device *sdev; 3331 struct srpt_device *sdev = client_data;
3332 int i; 3332 int i;
3333 3333
3334 sdev = ib_get_client_data(device, &srpt_client);
3335 if (!sdev) { 3334 if (!sdev) {
3336 pr_info("%s(%s): nothing to do.\n", __func__, device->name); 3335 pr_info("%s(%s): nothing to do.\n", __func__, device->name);
3337 return; 3336 return;
diff --git a/include/rdma/ib_verbs.h b/include/rdma/ib_verbs.h
index 7448a2740287..449609b70928 100644
--- a/include/rdma/ib_verbs.h
+++ b/include/rdma/ib_verbs.h
@@ -1550,6 +1550,8 @@ struct ib_device {
1550 1550
1551 spinlock_t client_data_lock; 1551 spinlock_t client_data_lock;
1552 struct list_head core_list; 1552 struct list_head core_list;
1553 /* Access to the client_data_list is protected by the client_data_lock
1554 * spinlock and the lists_rwsem read-write semaphore */
1553 struct list_head client_data_list; 1555 struct list_head client_data_list;
1554 1556
1555 struct ib_cache cache; 1557 struct ib_cache cache;
@@ -1761,7 +1763,7 @@ struct ib_device {
1761struct ib_client { 1763struct ib_client {
1762 char *name; 1764 char *name;
1763 void (*add) (struct ib_device *); 1765 void (*add) (struct ib_device *);
1764 void (*remove)(struct ib_device *); 1766 void (*remove)(struct ib_device *, void *client_data);
1765 1767
1766 struct list_head list; 1768 struct list_head list;
1767}; 1769};
diff --git a/net/rds/ib.c b/net/rds/ib.c
index ba2dffeff608..348ac37c1161 100644
--- a/net/rds/ib.c
+++ b/net/rds/ib.c
@@ -230,11 +230,10 @@ struct rds_ib_device *rds_ib_get_client_data(struct ib_device *device)
230 * 230 *
231 * This can be called at any time and can be racing with any other RDS path. 231 * This can be called at any time and can be racing with any other RDS path.
232 */ 232 */
233static void rds_ib_remove_one(struct ib_device *device) 233static void rds_ib_remove_one(struct ib_device *device, void *client_data)
234{ 234{
235 struct rds_ib_device *rds_ibdev; 235 struct rds_ib_device *rds_ibdev = client_data;
236 236
237 rds_ibdev = ib_get_client_data(device, &rds_ib_client);
238 if (!rds_ibdev) 237 if (!rds_ibdev)
239 return; 238 return;
240 239
diff --git a/net/rds/iw.c b/net/rds/iw.c
index 589935661d66..7cc2f32a0cb3 100644
--- a/net/rds/iw.c
+++ b/net/rds/iw.c
@@ -125,12 +125,11 @@ free_attr:
125 kfree(dev_attr); 125 kfree(dev_attr);
126} 126}
127 127
128static void rds_iw_remove_one(struct ib_device *device) 128static void rds_iw_remove_one(struct ib_device *device, void *client_data)
129{ 129{
130 struct rds_iw_device *rds_iwdev; 130 struct rds_iw_device *rds_iwdev = client_data;
131 struct rds_iw_cm_id *i_cm_id, *next; 131 struct rds_iw_cm_id *i_cm_id, *next;
132 132
133 rds_iwdev = ib_get_client_data(device, &rds_iw_client);
134 if (!rds_iwdev) 133 if (!rds_iwdev)
135 return; 134 return;
136 135