Skip to content

Commit 7efbd57

Browse files
Bang NguyenMukesh Kacker
authored andcommitted
rds/rdma_cm: send RDMA_CM_EVENT_ADDR_CHANGE event for active bonding
Orabug: 18421516 This patch is forward ported from ofa-2.6.32-400.1.1.el5.x86_64-1.5.5-4.1.15 Signed-off-by: Bang Nguyen <[email protected]> Signed-off-by: Avneesh Pant <[email protected]> Signed-off-by: Chien Yen <[email protected]> Signed-off-by: Ajaykumar Hotchandani <[email protected]> (cherry picked from commit b90f280baeedf4a56fae0c248d108ae118bb94ab) Signed-off-by: Jerry Snitselaar <[email protected]> Conflicts: drivers/infiniband/core/cma.c
1 parent 7a352a5 commit 7efbd57

File tree

5 files changed

+77
-0
lines changed

5 files changed

+77
-0
lines changed

drivers/infiniband/core/cma.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2267,6 +2267,42 @@ int rdma_set_reuseaddr(struct rdma_cm_id *id, int reuse)
22672267
}
22682268
EXPORT_SYMBOL(rdma_set_reuseaddr);
22692269

2270+
int rdma_notify_addr_change(struct sockaddr *addr)
2271+
{
2272+
struct cma_device *cma_dev;
2273+
struct rdma_id_private *id_priv;
2274+
struct sockaddr *src_addr;
2275+
struct cma_ndev_work *work;
2276+
int ret;
2277+
2278+
mutex_lock(&lock);
2279+
list_for_each_entry(cma_dev, &dev_list, list) {
2280+
list_for_each_entry(id_priv, &cma_dev->id_list, list) {
2281+
src_addr = (struct sockaddr *) &id_priv->id.route.addr.src_addr;
2282+
if (addr->sa_family == AF_INET &&
2283+
addr->sa_family == src_addr->sa_family &&
2284+
((struct sockaddr_in *) addr)->sin_addr.s_addr ==
2285+
((struct sockaddr_in *) src_addr)->sin_addr.s_addr) {
2286+
work = kzalloc(sizeof *work, GFP_ATOMIC);
2287+
if (!work) {
2288+
ret = -ENOMEM;
2289+
goto out;
2290+
}
2291+
2292+
INIT_WORK(&work->work, cma_ndev_work_handler);
2293+
work->id = id_priv;
2294+
work->event.event = RDMA_CM_EVENT_ADDR_CHANGE;
2295+
atomic_inc(&id_priv->refcount);
2296+
queue_work(cma_wq, &work->work);
2297+
}
2298+
}
2299+
}
2300+
out:
2301+
mutex_unlock(&lock);
2302+
return ret;
2303+
}
2304+
EXPORT_SYMBOL(rdma_notify_addr_change);
2305+
22702306
int rdma_set_afonly(struct rdma_cm_id *id, int afonly)
22712307
{
22722308
struct rdma_id_private *id_priv;

include/rdma/rdma_cm.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,14 @@ void rdma_destroy_id(struct rdma_cm_id *id);
191191
*/
192192
int rdma_bind_addr(struct rdma_cm_id *id, struct sockaddr *addr);
193193

194+
/**
195+
* rdma_notify_addr_change - Notify users that its IP has moved to a
196+
* different device.
197+
*
198+
* @addr: address information.
199+
*/
200+
int rdma_notify_addr_change(struct sockaddr *addr);
201+
194202
/**
195203
* rdma_resolve_addr - Resolve destination and optional source addresses
196204
* from IP addresses to an RDMA address. If successful, the specified

net/rds/ib.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -559,6 +559,22 @@ static void rds_ib_conn_drop(struct work_struct *_work)
559559
kfree(work);
560560
}
561561

562+
static void rds_ib_notify_addr_change(struct work_struct *_work)
563+
{
564+
struct rds_ib_addr_change_work *work =
565+
container_of(_work, struct rds_ib_addr_change_work, work.work);
566+
struct sockaddr_in sin;
567+
int ret;
568+
569+
sin.sin_family = AF_INET;
570+
sin.sin_addr.s_addr = work->addr;
571+
sin.sin_port = 0;
572+
573+
ret = rdma_notify_addr_change((struct sockaddr *)&sin);
574+
575+
kfree(work);
576+
}
577+
562578
static int rds_ib_move_ip(char *from_dev,
563579
char *to_dev,
564580
u8 from_port,
@@ -583,6 +599,7 @@ static int rds_ib_move_ip(char *from_dev,
583599
struct rds_ib_connection *ic, *ic2;
584600
struct rds_ib_device *rds_ibdev;
585601
struct rds_ib_conn_drop_work *work;
602+
struct rds_ib_addr_change_work *work_addrchange;
586603

587604
page = alloc_page(GFP_HIGHUSER);
588605
if (!page) {
@@ -779,6 +796,15 @@ static int rds_ib_move_ip(char *from_dev,
779796
}
780797
}
781798
spin_unlock_bh(&rds_ibdev->spinlock);
799+
800+
work_addrchange = kzalloc(sizeof *work, GFP_ATOMIC);
801+
if (!work_addrchange) {
802+
printk(KERN_WARNING "RDS/IB: failed to allocate work\n");
803+
goto out;
804+
}
805+
work_addrchange->addr = addr;
806+
INIT_DELAYED_WORK(&work_addrchange->work, rds_ib_notify_addr_change);
807+
queue_delayed_work(rds_wq, &work_addrchange->work, 10);
782808
}
783809

784810
out:

net/rds/ib.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,11 @@ struct rds_ib_conn_drop_work {
324324
struct rds_ib_connection *conn;
325325
};
326326

327+
struct rds_ib_addr_change_work {
328+
struct delayed_work work;
329+
__be32 addr;
330+
};
331+
327332
enum {
328333
RDS_IB_MR_8K_POOL,
329334
RDS_IB_MR_1M_POOL,

net/rds/rdma_transport.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,8 @@ int rds_rdma_cm_event_handler(struct rdma_cm_id *cm_id,
203203
break;
204204

205205
case RDMA_CM_EVENT_ADDR_CHANGE:
206+
rdsdebug("ADDR_CHANGE event <%u.%u.%u.%u,%u.%u.%u.%u>\n",
207+
NIPQUAD(conn->c_laddr), NIPQUAD(conn->c_faddr));
206208
#if RDMA_RDS_APM_SUPPORTED
207209
if (conn && !rds_ib_apm_enabled)
208210
rds_conn_drop(conn);

0 commit comments

Comments
 (0)