Skip to content

Commit e3d8841

Browse files
Bang NguyenMukesh Kacker
authored andcommitted
rds: dynamic active bonding configuration
OraBug: 18404635 This patch allows late joining interfaces to participate in IP failover/fallback operations. Signed-off-by: Bang Nguyen <[email protected]> Signed-off-by: Ajaykumar Hotchandani <[email protected]> Tested-by: Liwen Huang <[email protected]> (cherry picked from commit eb1b61e)
1 parent 78d0b34 commit e3d8841

File tree

1 file changed

+85
-38
lines changed

1 file changed

+85
-38
lines changed

net/rds/ib.c

Lines changed: 85 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -788,38 +788,6 @@ static int rds_ib_move_ip(char *from_dev,
788788
return ret;
789789
}
790790

791-
static void rds_ib_check_up_port(void)
792-
{
793-
struct net_device *dev;
794-
int downs;
795-
int retries = 0;
796-
797-
retry:
798-
downs = 0;
799-
read_lock(&dev_base_lock);
800-
for_each_netdev(&init_net, dev) {
801-
if ((dev->type == ARPHRD_INFINIBAND) &&
802-
(dev->flags & IFF_UP) &&
803-
!(dev->flags & IFF_SLAVE) &&
804-
!(dev->flags & IFF_MASTER)) {
805-
if (dev->operstate != IF_OPER_UP)
806-
downs++;
807-
}
808-
}
809-
read_unlock(&dev_base_lock);
810-
811-
if (downs) {
812-
if (retries++ <= 30) {
813-
msleep(1000);
814-
goto retry;
815-
} else {
816-
printk(KERN_ERR "RDS/IB: Some port(s) may not be "
817-
"operational\n");
818-
}
819-
}
820-
}
821-
822-
823791
static u8 rds_ib_init_port(struct rds_ib_device *rds_ibdev,
824792
struct net_device *net_dev,
825793
u8 port_num,
@@ -1186,9 +1154,8 @@ static void rds_ib_dump_ip_config(void)
11861154
if (!rds_ib_active_bonding_enabled || !ip_port_cnt)
11871155
return;
11881156

1189-
printk(KERN_ERR "RDS/IB: IP configuration ...\n");
11901157
for (i = 1; i <= ip_port_cnt; i++) {
1191-
printk(KERN_ERR "RDS/IB: %s/port_%d/%s: "
1158+
printk(KERN_INFO "RDS/IB: %s/port_%d/%s: "
11921159
"IP %d.%d.%d.%d/%d.%d.%d.%d/%d.%d.%d.%d "
11931160
"state %s\n",
11941161
((ip_config[i].rds_ibdev) ?
@@ -1205,7 +1172,7 @@ static void rds_ib_dump_ip_config(void)
12051172
RDS_IB_PORT_UP ? "UP" : "DOWN"));
12061173

12071174
for (j = 0; j < ip_config[i].alias_cnt; j++) {
1208-
printk(KERN_ERR "Alias %s "
1175+
printk(KERN_INFO "Alias %s "
12091176
"IP %d.%d.%d.%d/%d.%d.%d.%d/%d.%d.%d.%d\n",
12101177
ip_config[i].aliases[j].if_name,
12111178
NIPQUAD(ip_config[i].
@@ -1233,8 +1200,6 @@ static int rds_ib_ip_config_init(void)
12331200
if (!rds_ib_active_bonding_enabled)
12341201
return 0;
12351202

1236-
rds_ib_check_up_port();
1237-
12381203
rcu_read_unlock();
12391204

12401205
ip_config = kzalloc(sizeof(struct rds_ib_port) *
@@ -1287,6 +1252,7 @@ static int rds_ib_ip_config_init(void)
12871252
in_dev_put(in_dev);
12881253
}
12891254

1255+
printk(KERN_INFO "RDS/IB: IP configuration..\n");
12901256
rds_ib_dump_ip_config();
12911257
read_unlock(&dev_base_lock);
12921258
return ret;
@@ -1602,14 +1568,76 @@ static void rds_ib_update_ip_config(void)
16021568
read_unlock(&dev_base_lock);
16031569
}
16041570

1571+
static void rds_ib_joining_ip(struct work_struct *_work)
1572+
{
1573+
struct rds_ib_port_ud_work *work =
1574+
container_of(_work, struct rds_ib_port_ud_work, work.work);
1575+
struct net_device *ndev = work->dev;
1576+
struct in_ifaddr *ifa;
1577+
struct in_ifaddr **ifap;
1578+
struct in_device *in_dev;
1579+
union ib_gid gid;
1580+
struct rds_ib_device *rds_ibdev;
1581+
int ret = 0;
1582+
u8 port_num;
1583+
u8 port;
1584+
1585+
read_lock(&dev_base_lock);
1586+
in_dev = in_dev_get(ndev);
1587+
if (in_dev && !in_dev->ifa_list && work->timeout > 0) {
1588+
INIT_DELAYED_WORK(&work->work, rds_ib_joining_ip);
1589+
work->timeout -= msecs_to_jiffies(100);
1590+
queue_delayed_work(rds_wq, &work->work, msecs_to_jiffies(100));
1591+
} else if (in_dev && in_dev->ifa_list) {
1592+
memcpy(&gid, ndev->dev_addr + 4, sizeof gid);
1593+
list_for_each_entry_rcu(rds_ibdev,
1594+
&rds_ib_devices, list) {
1595+
ret = ib_find_cached_gid(rds_ibdev->dev,
1596+
&gid, &port_num, NULL);
1597+
if (!ret)
1598+
break;
1599+
}
1600+
if (ret) {
1601+
printk(KERN_ERR "RDS/IB: GID "RDS_IB_GID_FMT
1602+
" has no associated port\n",
1603+
RDS_IB_GID_ARG(gid));
1604+
} else {
1605+
port = rds_ib_init_port(rds_ibdev, ndev,
1606+
port_num, gid);
1607+
if (port > 0) {
1608+
for (ifap = &in_dev->ifa_list;
1609+
(ifa = *ifap);
1610+
ifap = &ifa->ifa_next) {
1611+
rds_ib_set_port(rds_ibdev, ndev,
1612+
ifa->ifa_label,
1613+
port,
1614+
ifa->ifa_address,
1615+
ifa->ifa_broadcast,
1616+
ifa->ifa_mask);
1617+
}
1618+
}
1619+
}
1620+
printk(KERN_INFO "RDS/IB: Updated IP configuration..\n");
1621+
rds_ib_ip_failover_groups_init();
1622+
rds_ib_dump_ip_config();
1623+
kfree(work);
1624+
} else if (!work->timeout)
1625+
kfree(work);
1626+
1627+
if (in_dev)
1628+
in_dev_put(in_dev);
1629+
read_unlock(&dev_base_lock);
1630+
}
1631+
1632+
16051633
static int rds_ib_netdev_callback(struct notifier_block *self, unsigned long event, void *ctx)
16061634
{
16071635
struct net_device *ndev = netdev_notifier_info_to_dev(ctx);
16081636
u8 port = 0;
16091637
u8 i;
16101638
struct rds_ib_port_ud_work *work = NULL;
16111639

1612-
if (!rds_ib_active_bonding_enabled || !ip_port_cnt)
1640+
if (!rds_ib_active_bonding_enabled)
16131641
return NOTIFY_DONE;
16141642

16151643
if (event != NETDEV_UP && event != NETDEV_DOWN)
@@ -1625,6 +1653,25 @@ static int rds_ib_netdev_callback(struct notifier_block *self, unsigned long eve
16251653
}
16261654
}
16271655

1656+
/* check for newly joined IB interface */
1657+
if (!port && event == NETDEV_UP) {
1658+
if ((ndev->type == ARPHRD_INFINIBAND) &&
1659+
(ndev->flags & IFF_UP) &&
1660+
!(ndev->flags & IFF_SLAVE) &&
1661+
!(ndev->flags & IFF_MASTER)) {
1662+
work = kzalloc(sizeof *work, GFP_ATOMIC);
1663+
if (work) {
1664+
work->dev = ndev;
1665+
work->timeout = msecs_to_jiffies(10000);
1666+
INIT_DELAYED_WORK(&work->work, rds_ib_joining_ip);
1667+
queue_delayed_work(rds_wq, &work->work,
1668+
msecs_to_jiffies(100));
1669+
}
1670+
}
1671+
1672+
return NOTIFY_DONE;
1673+
}
1674+
16281675
if (!port)
16291676
return NOTIFY_DONE;
16301677

0 commit comments

Comments
 (0)