Skip to content

Commit eb1b61e

Browse files
Bang NguyenJerry Snitselaar
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]>
1 parent ad955d9 commit eb1b61e

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
@@ -770,38 +770,6 @@ static int rds_ib_move_ip(char *from_dev,
770770
return ret;
771771
}
772772

773-
static void rds_ib_check_up_port(void)
774-
{
775-
struct net_device *dev;
776-
int downs;
777-
int retries = 0;
778-
779-
retry:
780-
downs = 0;
781-
read_lock(&dev_base_lock);
782-
for_each_netdev(&init_net, dev) {
783-
if ((dev->type == ARPHRD_INFINIBAND) &&
784-
(dev->flags & IFF_UP) &&
785-
!(dev->flags & IFF_SLAVE) &&
786-
!(dev->flags & IFF_MASTER)) {
787-
if (dev->operstate != IF_OPER_UP)
788-
downs++;
789-
}
790-
}
791-
read_unlock(&dev_base_lock);
792-
793-
if (downs) {
794-
if (retries++ <= 30) {
795-
msleep(1000);
796-
goto retry;
797-
} else {
798-
printk(KERN_ERR "RDS/IB: Some port(s) may not be "
799-
"operational\n");
800-
}
801-
}
802-
}
803-
804-
805773
static u8 rds_ib_init_port(struct rds_ib_device *rds_ibdev,
806774
struct net_device *net_dev,
807775
u8 port_num,
@@ -1168,9 +1136,8 @@ static void rds_ib_dump_ip_config(void)
11681136
if (!rds_ib_active_bonding_enabled || !ip_port_cnt)
11691137
return;
11701138

1171-
printk(KERN_ERR "RDS/IB: IP configuration ...\n");
11721139
for (i = 1; i <= ip_port_cnt; i++) {
1173-
printk(KERN_ERR "RDS/IB: %s/port_%d/%s: "
1140+
printk(KERN_INFO "RDS/IB: %s/port_%d/%s: "
11741141
"IP %d.%d.%d.%d/%d.%d.%d.%d/%d.%d.%d.%d "
11751142
"state %s\n",
11761143
((ip_config[i].rds_ibdev) ?
@@ -1187,7 +1154,7 @@ static void rds_ib_dump_ip_config(void)
11871154
RDS_IB_PORT_UP ? "UP" : "DOWN"));
11881155

11891156
for (j = 0; j < ip_config[i].alias_cnt; j++) {
1190-
printk(KERN_ERR "Alias %s "
1157+
printk(KERN_INFO "Alias %s "
11911158
"IP %d.%d.%d.%d/%d.%d.%d.%d/%d.%d.%d.%d\n",
11921159
ip_config[i].aliases[j].if_name,
11931160
NIPQUAD(ip_config[i].
@@ -1215,8 +1182,6 @@ static int rds_ib_ip_config_init(void)
12151182
if (!rds_ib_active_bonding_enabled)
12161183
return 0;
12171184

1218-
rds_ib_check_up_port();
1219-
12201185
rcu_read_unlock();
12211186

12221187
ip_config = kzalloc(sizeof(struct rds_ib_port) *
@@ -1269,6 +1234,7 @@ static int rds_ib_ip_config_init(void)
12691234
in_dev_put(in_dev);
12701235
}
12711236

1237+
printk(KERN_INFO "RDS/IB: IP configuration..\n");
12721238
rds_ib_dump_ip_config();
12731239
read_unlock(&dev_base_lock);
12741240
return ret;
@@ -1585,14 +1551,76 @@ static void rds_ib_update_ip_config(void)
15851551
read_unlock(&dev_base_lock);
15861552
}
15871553

1554+
static void rds_ib_joining_ip(struct work_struct *_work)
1555+
{
1556+
struct rds_ib_port_ud_work *work =
1557+
container_of(_work, struct rds_ib_port_ud_work, work.work);
1558+
struct net_device *ndev = work->dev;
1559+
struct in_ifaddr *ifa;
1560+
struct in_ifaddr **ifap;
1561+
struct in_device *in_dev;
1562+
union ib_gid gid;
1563+
struct rds_ib_device *rds_ibdev;
1564+
int ret = 0;
1565+
u8 port_num;
1566+
u8 port;
1567+
1568+
read_lock(&dev_base_lock);
1569+
in_dev = in_dev_get(ndev);
1570+
if (in_dev && !in_dev->ifa_list && work->timeout > 0) {
1571+
INIT_DELAYED_WORK(&work->work, rds_ib_joining_ip);
1572+
work->timeout -= msecs_to_jiffies(100);
1573+
queue_delayed_work(rds_wq, &work->work, msecs_to_jiffies(100));
1574+
} else if (in_dev && in_dev->ifa_list) {
1575+
memcpy(&gid, ndev->dev_addr + 4, sizeof gid);
1576+
list_for_each_entry_rcu(rds_ibdev,
1577+
&rds_ib_devices, list) {
1578+
ret = ib_find_cached_gid(rds_ibdev->dev,
1579+
&gid, &port_num, NULL);
1580+
if (!ret)
1581+
break;
1582+
}
1583+
if (ret) {
1584+
printk(KERN_ERR "RDS/IB: GID "RDS_IB_GID_FMT
1585+
" has no associated port\n",
1586+
RDS_IB_GID_ARG(gid));
1587+
} else {
1588+
port = rds_ib_init_port(rds_ibdev, ndev,
1589+
port_num, gid);
1590+
if (port > 0) {
1591+
for (ifap = &in_dev->ifa_list;
1592+
(ifa = *ifap);
1593+
ifap = &ifa->ifa_next) {
1594+
rds_ib_set_port(rds_ibdev, ndev,
1595+
ifa->ifa_label,
1596+
port,
1597+
ifa->ifa_address,
1598+
ifa->ifa_broadcast,
1599+
ifa->ifa_mask);
1600+
}
1601+
}
1602+
}
1603+
printk(KERN_INFO "RDS/IB: Updated IP configuration..\n");
1604+
rds_ib_ip_failover_groups_init();
1605+
rds_ib_dump_ip_config();
1606+
kfree(work);
1607+
} else if (!work->timeout)
1608+
kfree(work);
1609+
1610+
if (in_dev)
1611+
in_dev_put(in_dev);
1612+
read_unlock(&dev_base_lock);
1613+
}
1614+
1615+
15881616
static int rds_ib_netdev_callback(struct notifier_block *self, unsigned long event, void *ctx)
15891617
{
15901618
struct net_device *ndev = (struct net_device *)ctx;
15911619
u8 port = 0;
15921620
u8 i;
15931621
struct rds_ib_port_ud_work *work;
15941622

1595-
if (!rds_ib_active_bonding_enabled || !ip_port_cnt)
1623+
if (!rds_ib_active_bonding_enabled)
15961624
return NOTIFY_DONE;
15971625

15981626
if (event != NETDEV_UP && event != NETDEV_DOWN)
@@ -1608,6 +1636,25 @@ static int rds_ib_netdev_callback(struct notifier_block *self, unsigned long eve
16081636
}
16091637
}
16101638

1639+
/* check for newly joined IB interface */
1640+
if (!port && event == NETDEV_UP) {
1641+
if ((ndev->type == ARPHRD_INFINIBAND) &&
1642+
(ndev->flags & IFF_UP) &&
1643+
!(ndev->flags & IFF_SLAVE) &&
1644+
!(ndev->flags & IFF_MASTER)) {
1645+
work = kzalloc(sizeof *work, GFP_ATOMIC);
1646+
if (work) {
1647+
work->dev = ndev;
1648+
work->timeout = msecs_to_jiffies(10000);
1649+
INIT_DELAYED_WORK(&work->work, rds_ib_joining_ip);
1650+
queue_delayed_work(rds_wq, &work->work,
1651+
msecs_to_jiffies(100));
1652+
}
1653+
}
1654+
1655+
return NOTIFY_DONE;
1656+
}
1657+
16111658
if (!port)
16121659
return NOTIFY_DONE;
16131660

0 commit comments

Comments
 (0)