Jelajahi Sumber

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>
Ying Xue 7 tahun lalu
induk
melakukan
e5d1a1eec0
1 mengubah file dengan 15 tambahan dan 14 penghapusan
  1. 15 14
      net/tipc/netlink_compat.c

+ 15 - 14
net/tipc/netlink_compat.c

@@ -285,10 +285,6 @@ static int __tipc_nl_compat_doit(struct tipc_nl_compat_cmd_doit *cmd,
 	if (!trans_buf)
 	if (!trans_buf)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
-	err = (*cmd->transcode)(cmd, trans_buf, msg);
-	if (err)
-		goto trans_out;
-
 	attrbuf = kmalloc((tipc_genl_family.maxattr + 1) *
 	attrbuf = kmalloc((tipc_genl_family.maxattr + 1) *
 			sizeof(struct nlattr *), GFP_KERNEL);
 			sizeof(struct nlattr *), GFP_KERNEL);
 	if (!attrbuf) {
 	if (!attrbuf) {
@@ -296,27 +292,32 @@ static int __tipc_nl_compat_doit(struct tipc_nl_compat_cmd_doit *cmd,
 		goto trans_out;
 		goto trans_out;
 	}
 	}
 
 
-	err = nla_parse(attrbuf, tipc_genl_family.maxattr,
-			(const struct nlattr *)trans_buf->data,
-			trans_buf->len, NULL, NULL);
-	if (err)
-		goto parse_out;
-
 	doit_buf = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
 	doit_buf = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
 	if (!doit_buf) {
 	if (!doit_buf) {
 		err = -ENOMEM;
 		err = -ENOMEM;
-		goto parse_out;
+		goto attrbuf_out;
 	}
 	}
 
 
-	doit_buf->sk = msg->dst_sk;
-
 	memset(&info, 0, sizeof(info));
 	memset(&info, 0, sizeof(info));
 	info.attrs = attrbuf;
 	info.attrs = attrbuf;
 
 
+	err = (*cmd->transcode)(cmd, trans_buf, msg);
+	if (err)
+		goto doit_out;
+
+	err = nla_parse(attrbuf, tipc_genl_family.maxattr,
+			(const struct nlattr *)trans_buf->data,
+			trans_buf->len, NULL, NULL);
+	if (err)
+		goto doit_out;
+
+	doit_buf->sk = msg->dst_sk;
+
 	err = (*cmd->doit)(doit_buf, &info);
 	err = (*cmd->doit)(doit_buf, &info);
+doit_out:
 
 
 	kfree_skb(doit_buf);
 	kfree_skb(doit_buf);
-parse_out:
+attrbuf_out:
 	kfree(attrbuf);
 	kfree(attrbuf);
 trans_out:
 trans_out:
 	kfree_skb(trans_buf);
 	kfree_skb(trans_buf);