diff options
author | Ying Xue <ying.xue@windriver.com> | 2018-02-14 00:37:58 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2018-02-14 14:46:32 -0500 |
commit | e5d1a1eec0f4b51d0a7a6457d0b1b99b34f3e901 (patch) | |
tree | 73be7be8911658b34337ca861ce2efdb1f62e535 /net/tipc | |
parent | 361b1231801944ddecbd0e383420932633cac2d1 (diff) |
tipc: Refactor __tipc_nl_compat_doit
As preparation for adding RTNL to make (*cmd->transcode)() and
(*cmd->transcode)() constantly protected by RTNL lock, we move out of
memory allocations existing between them as many as possible so that
the time of holding RTNL can be minimized in __tipc_nl_compat_doit().
Signed-off-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/tipc')
-rw-r--r-- | net/tipc/netlink_compat.c | 29 |
1 files changed, 15 insertions, 14 deletions
diff --git a/net/tipc/netlink_compat.c b/net/tipc/netlink_compat.c index e48f0b2c01b9..974169059b9c 100644 --- a/net/tipc/netlink_compat.c +++ b/net/tipc/netlink_compat.c | |||
@@ -285,10 +285,6 @@ static int __tipc_nl_compat_doit(struct tipc_nl_compat_cmd_doit *cmd, | |||
285 | if (!trans_buf) | 285 | if (!trans_buf) |
286 | return -ENOMEM; | 286 | return -ENOMEM; |
287 | 287 | ||
288 | err = (*cmd->transcode)(cmd, trans_buf, msg); | ||
289 | if (err) | ||
290 | goto trans_out; | ||
291 | |||
292 | attrbuf = kmalloc((tipc_genl_family.maxattr + 1) * | 288 | attrbuf = kmalloc((tipc_genl_family.maxattr + 1) * |
293 | sizeof(struct nlattr *), GFP_KERNEL); | 289 | sizeof(struct nlattr *), GFP_KERNEL); |
294 | if (!attrbuf) { | 290 | if (!attrbuf) { |
@@ -296,27 +292,32 @@ static int __tipc_nl_compat_doit(struct tipc_nl_compat_cmd_doit *cmd, | |||
296 | goto trans_out; | 292 | goto trans_out; |
297 | } | 293 | } |
298 | 294 | ||
299 | err = nla_parse(attrbuf, tipc_genl_family.maxattr, | ||
300 | (const struct nlattr *)trans_buf->data, | ||
301 | trans_buf->len, NULL, NULL); | ||
302 | if (err) | ||
303 | goto parse_out; | ||
304 | |||
305 | doit_buf = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); | 295 | doit_buf = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); |
306 | if (!doit_buf) { | 296 | if (!doit_buf) { |
307 | err = -ENOMEM; | 297 | err = -ENOMEM; |
308 | goto parse_out; | 298 | goto attrbuf_out; |
309 | } | 299 | } |
310 | 300 | ||
311 | doit_buf->sk = msg->dst_sk; | ||
312 | |||
313 | memset(&info, 0, sizeof(info)); | 301 | memset(&info, 0, sizeof(info)); |
314 | info.attrs = attrbuf; | 302 | info.attrs = attrbuf; |
315 | 303 | ||
304 | err = (*cmd->transcode)(cmd, trans_buf, msg); | ||
305 | if (err) | ||
306 | goto doit_out; | ||
307 | |||
308 | err = nla_parse(attrbuf, tipc_genl_family.maxattr, | ||
309 | (const struct nlattr *)trans_buf->data, | ||
310 | trans_buf->len, NULL, NULL); | ||
311 | if (err) | ||
312 | goto doit_out; | ||
313 | |||
314 | doit_buf->sk = msg->dst_sk; | ||
315 | |||
316 | err = (*cmd->doit)(doit_buf, &info); | 316 | err = (*cmd->doit)(doit_buf, &info); |
317 | doit_out: | ||
317 | 318 | ||
318 | kfree_skb(doit_buf); | 319 | kfree_skb(doit_buf); |
319 | parse_out: | 320 | attrbuf_out: |
320 | kfree(attrbuf); | 321 | kfree(attrbuf); |
321 | trans_out: | 322 | trans_out: |
322 | kfree_skb(trans_buf); | 323 | kfree_skb(trans_buf); |