Skip to content

Commit b7d2fc9

Browse files
q2venPaolo Abeni
authored andcommitted
phonet: Don't hold RTNL for getaddr_dumpit().
getaddr_dumpit() already relies on RCU and does not need RTNL. Let's use READ_ONCE() for ifindex and register getaddr_dumpit() with RTNL_FLAG_DUMP_UNLOCKED. While at it, the retval of getaddr_dumpit() is changed to combine NLMSG_DONE and save recvmsg() as done in 58a4ff5 ("phonet: no longer hold RTNL in route_dumpit()"). Signed-off-by: Kuniyuki Iwashima <[email protected]> Reviewed-by: Eric Dumazet <[email protected]> Signed-off-by: Paolo Abeni <[email protected]>
1 parent 8786e98 commit b7d2fc9

File tree

1 file changed

+15
-9
lines changed

1 file changed

+15
-9
lines changed

net/phonet/pn_netlink.c

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -127,14 +127,17 @@ static int fill_addr(struct sk_buff *skb, u32 ifindex, u8 addr,
127127

128128
static int getaddr_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
129129
{
130+
int addr_idx = 0, addr_start_idx = cb->args[1];
131+
int dev_idx = 0, dev_start_idx = cb->args[0];
130132
struct phonet_device_list *pndevs;
131133
struct phonet_device *pnd;
132-
int dev_idx = 0, dev_start_idx = cb->args[0];
133-
int addr_idx = 0, addr_start_idx = cb->args[1];
134+
int err = 0;
134135

135136
pndevs = phonet_device_list(sock_net(skb->sk));
137+
136138
rcu_read_lock();
137139
list_for_each_entry_rcu(pnd, &pndevs->list, list) {
140+
DECLARE_BITMAP(addrs, 64);
138141
u8 addr;
139142

140143
if (dev_idx > dev_start_idx)
@@ -143,23 +146,26 @@ static int getaddr_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
143146
continue;
144147

145148
addr_idx = 0;
146-
for_each_set_bit(addr, pnd->addrs, 64) {
149+
memcpy(addrs, pnd->addrs, sizeof(pnd->addrs));
150+
151+
for_each_set_bit(addr, addrs, 64) {
147152
if (addr_idx++ < addr_start_idx)
148153
continue;
149154

150-
if (fill_addr(skb, pnd->netdev->ifindex, addr << 2,
151-
NETLINK_CB(cb->skb).portid,
152-
cb->nlh->nlmsg_seq, RTM_NEWADDR) < 0)
155+
err = fill_addr(skb, READ_ONCE(pnd->netdev->ifindex),
156+
addr << 2, NETLINK_CB(cb->skb).portid,
157+
cb->nlh->nlmsg_seq, RTM_NEWADDR);
158+
if (err < 0)
153159
goto out;
154160
}
155161
}
156-
157162
out:
158163
rcu_read_unlock();
164+
159165
cb->args[0] = dev_idx;
160166
cb->args[1] = addr_idx;
161167

162-
return skb->len;
168+
return err;
163169
}
164170

165171
/* Routes handling */
@@ -298,7 +304,7 @@ static const struct rtnl_msg_handler phonet_rtnl_msg_handlers[] __initdata_or_mo
298304
{.owner = THIS_MODULE, .protocol = PF_PHONET, .msgtype = RTM_DELADDR,
299305
.doit = addr_doit, .flags = RTNL_FLAG_DOIT_UNLOCKED},
300306
{.owner = THIS_MODULE, .protocol = PF_PHONET, .msgtype = RTM_GETADDR,
301-
.dumpit = getaddr_dumpit},
307+
.dumpit = getaddr_dumpit, .flags = RTNL_FLAG_DUMP_UNLOCKED},
302308
{.owner = THIS_MODULE, .protocol = PF_PHONET, .msgtype = RTM_NEWROUTE,
303309
.doit = route_doit},
304310
{.owner = THIS_MODULE, .protocol = PF_PHONET, .msgtype = RTM_DELROUTE,

0 commit comments

Comments
 (0)