All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC 0/7] genetlink: reduce ops size and complexity
@ 2013-11-14  9:14 Johannes Berg
  2013-11-14  9:14 ` [RFC 1/7] taskstats: use genl_register_family_with_ops() Johannes Berg
                   ` (11 more replies)
  0 siblings, 12 replies; 29+ messages in thread
From: Johannes Berg @ 2013-11-14  9:14 UTC (permalink / raw)
  To: netdev

This series of patches updates a few genetlink users and then
makes the ops a static const array, reducing kernel size and
code complexity.

Comments welcome.

johannes

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [RFC 1/7] taskstats: use genl_register_family_with_ops()
  2013-11-14  9:14 [RFC 0/7] genetlink: reduce ops size and complexity Johannes Berg
@ 2013-11-14  9:14 ` Johannes Berg
  2013-11-14  9:14 ` [RFC 2/7] hsr: " Johannes Berg
                   ` (10 subsequent siblings)
  11 siblings, 0 replies; 29+ messages in thread
From: Johannes Berg @ 2013-11-14  9:14 UTC (permalink / raw)
  To: netdev; +Cc: Johannes Berg

From: Johannes Berg <johannes.berg@intel.com>

This simplifies the code since there's no longer a
need to have error handling in the registration.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 kernel/taskstats.c | 39 ++++++++++++++-------------------------
 1 file changed, 14 insertions(+), 25 deletions(-)

diff --git a/kernel/taskstats.c b/kernel/taskstats.c
index 9f4618e..609e77f 100644
--- a/kernel/taskstats.c
+++ b/kernel/taskstats.c
@@ -673,17 +673,18 @@ err:
 	nlmsg_free(rep_skb);
 }
 
-static struct genl_ops taskstats_ops = {
-	.cmd		= TASKSTATS_CMD_GET,
-	.doit		= taskstats_user_cmd,
-	.policy		= taskstats_cmd_get_policy,
-	.flags		= GENL_ADMIN_PERM,
-};
-
-static struct genl_ops cgroupstats_ops = {
-	.cmd		= CGROUPSTATS_CMD_GET,
-	.doit		= cgroupstats_user_cmd,
-	.policy		= cgroupstats_cmd_get_policy,
+static struct genl_ops taskstats_ops[] = {
+	{
+		.cmd		= TASKSTATS_CMD_GET,
+		.doit		= taskstats_user_cmd,
+		.policy		= taskstats_cmd_get_policy,
+		.flags		= GENL_ADMIN_PERM,
+	},
+	{
+		.cmd		= CGROUPSTATS_CMD_GET,
+		.doit		= cgroupstats_user_cmd,
+		.policy		= cgroupstats_cmd_get_policy,
+	},
 };
 
 /* Needed early in initialization */
@@ -702,26 +703,14 @@ static int __init taskstats_init(void)
 {
 	int rc;
 
-	rc = genl_register_family(&family);
+	rc = genl_register_family_with_ops(&family, taskstats_ops,
+					   ARRAY_SIZE(taskstats_ops));
 	if (rc)
 		return rc;
 
-	rc = genl_register_ops(&family, &taskstats_ops);
-	if (rc < 0)
-		goto err;
-
-	rc = genl_register_ops(&family, &cgroupstats_ops);
-	if (rc < 0)
-		goto err_cgroup_ops;
-
 	family_registered = 1;
 	pr_info("registered taskstats version %d\n", TASKSTATS_GENL_VERSION);
 	return 0;
-err_cgroup_ops:
-	genl_unregister_ops(&family, &taskstats_ops);
-err:
-	genl_unregister_family(&family);
-	return rc;
 }
 
 /*
-- 
1.8.4.rc3

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [RFC 2/7] hsr: use genl_register_family_with_ops()
  2013-11-14  9:14 [RFC 0/7] genetlink: reduce ops size and complexity Johannes Berg
  2013-11-14  9:14 ` [RFC 1/7] taskstats: use genl_register_family_with_ops() Johannes Berg
@ 2013-11-14  9:14 ` Johannes Berg
  2013-11-14  9:14 ` [RFC 3/7] ieee802154: " Johannes Berg
                   ` (9 subsequent siblings)
  11 siblings, 0 replies; 29+ messages in thread
From: Johannes Berg @ 2013-11-14  9:14 UTC (permalink / raw)
  To: netdev; +Cc: Johannes Berg

From: Johannes Berg <johannes.berg@intel.com>

This simplifies the code since there's no longer a
need to have error handling in the registration.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 net/hsr/hsr_netlink.c | 46 +++++++++++++++++-----------------------------
 1 file changed, 17 insertions(+), 29 deletions(-)

diff --git a/net/hsr/hsr_netlink.c b/net/hsr/hsr_netlink.c
index 4e66bf6..8f52a9f 100644
--- a/net/hsr/hsr_netlink.c
+++ b/net/hsr/hsr_netlink.c
@@ -306,15 +306,6 @@ fail:
 	return res;
 }
 
-static struct genl_ops hsr_ops_get_node_status = {
-	.cmd = HSR_C_GET_NODE_STATUS,
-	.flags = 0,
-	.policy = hsr_genl_policy,
-	.doit = hsr_get_node_status,
-	.dumpit = NULL,
-};
-
-
 /* Get a list of MacAddressA of all nodes known to this node (other than self).
  */
 static int hsr_get_node_list(struct sk_buff *skb_in, struct genl_info *info)
@@ -398,12 +389,21 @@ fail:
 }
 
 
-static struct genl_ops hsr_ops_get_node_list = {
-	.cmd = HSR_C_GET_NODE_LIST,
-	.flags = 0,
-	.policy = hsr_genl_policy,
-	.doit = hsr_get_node_list,
-	.dumpit = NULL,
+static struct genl_ops hsr_ops[] = {
+	{
+		.cmd = HSR_C_GET_NODE_STATUS,
+		.flags = 0,
+		.policy = hsr_genl_policy,
+		.doit = hsr_get_node_status,
+		.dumpit = NULL,
+	},
+	{
+		.cmd = HSR_C_GET_NODE_LIST,
+		.flags = 0,
+		.policy = hsr_genl_policy,
+		.doit = hsr_get_node_list,
+		.dumpit = NULL,
+	},
 };
 
 int __init hsr_netlink_init(void)
@@ -414,18 +414,11 @@ int __init hsr_netlink_init(void)
 	if (rc)
 		goto fail_rtnl_link_register;
 
-	rc = genl_register_family(&hsr_genl_family);
+	rc = genl_register_family_with_ops(&hsr_genl_family, hsr_ops,
+					   ARRAY_SIZE(hsr_ops));
 	if (rc)
 		goto fail_genl_register_family;
 
-	rc = genl_register_ops(&hsr_genl_family, &hsr_ops_get_node_status);
-	if (rc)
-		goto fail_genl_register_ops;
-
-	rc = genl_register_ops(&hsr_genl_family, &hsr_ops_get_node_list);
-	if (rc)
-		goto fail_genl_register_ops_node_list;
-
 	rc = genl_register_mc_group(&hsr_genl_family, &hsr_network_genl_mcgrp);
 	if (rc)
 		goto fail_genl_register_mc_group;
@@ -433,10 +426,6 @@ int __init hsr_netlink_init(void)
 	return 0;
 
 fail_genl_register_mc_group:
-	genl_unregister_ops(&hsr_genl_family, &hsr_ops_get_node_list);
-fail_genl_register_ops_node_list:
-	genl_unregister_ops(&hsr_genl_family, &hsr_ops_get_node_status);
-fail_genl_register_ops:
 	genl_unregister_family(&hsr_genl_family);
 fail_genl_register_family:
 	rtnl_link_unregister(&hsr_link_ops);
@@ -448,7 +437,6 @@ fail_rtnl_link_register:
 void __exit hsr_netlink_exit(void)
 {
 	genl_unregister_mc_group(&hsr_genl_family, &hsr_network_genl_mcgrp);
-	genl_unregister_ops(&hsr_genl_family, &hsr_ops_get_node_status);
 	genl_unregister_family(&hsr_genl_family);
 
 	rtnl_link_unregister(&hsr_link_ops);
-- 
1.8.4.rc3

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [RFC 3/7] ieee802154: use genl_register_family_with_ops()
  2013-11-14  9:14 [RFC 0/7] genetlink: reduce ops size and complexity Johannes Berg
  2013-11-14  9:14 ` [RFC 1/7] taskstats: use genl_register_family_with_ops() Johannes Berg
  2013-11-14  9:14 ` [RFC 2/7] hsr: " Johannes Berg
@ 2013-11-14  9:14 ` Johannes Berg
  2013-11-14  9:14 ` [RFC 4/7] wimax: " Johannes Berg
                   ` (8 subsequent siblings)
  11 siblings, 0 replies; 29+ messages in thread
From: Johannes Berg @ 2013-11-14  9:14 UTC (permalink / raw)
  To: netdev; +Cc: Johannes Berg

From: Johannes Berg <johannes.berg@intel.com>

This simplifies the code since there's no longer a need to
have error handling in the registration.

Unfortunately it means more extern function declarations are
needed, but the overall goal would seem to justify this.

While at it, also fix the registration error path - if the
family registration failed then it shouldn't be unregistered.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 net/ieee802154/ieee802154.h | 19 ++++++++++++--
 net/ieee802154/netlink.c    | 28 +++++++++++++++------
 net/ieee802154/nl-mac.c     | 61 +++++++--------------------------------------
 net/ieee802154/nl-phy.c     | 37 +++------------------------
 4 files changed, 51 insertions(+), 94 deletions(-)

diff --git a/net/ieee802154/ieee802154.h b/net/ieee802154/ieee802154.h
index aadec42..14d5dab 100644
--- a/net/ieee802154/ieee802154.h
+++ b/net/ieee802154/ieee802154.h
@@ -47,7 +47,22 @@ struct sk_buff *ieee802154_nl_new_reply(struct genl_info *info,
 int ieee802154_nl_reply(struct sk_buff *msg, struct genl_info *info);
 
 extern struct genl_family nl802154_family;
-int nl802154_mac_register(void);
-int nl802154_phy_register(void);
+
+/* genetlink ops/groups */
+int ieee802154_list_phy(struct sk_buff *skb, struct genl_info *info);
+int ieee802154_dump_phy(struct sk_buff *skb, struct netlink_callback *cb);
+int ieee802154_add_iface(struct sk_buff *skb, struct genl_info *info);
+int ieee802154_del_iface(struct sk_buff *skb, struct genl_info *info);
+
+extern struct genl_multicast_group ieee802154_coord_mcgrp;
+extern struct genl_multicast_group ieee802154_beacon_mcgrp;
+
+int ieee802154_associate_req(struct sk_buff *skb, struct genl_info *info);
+int ieee802154_associate_resp(struct sk_buff *skb, struct genl_info *info);
+int ieee802154_disassociate_req(struct sk_buff *skb, struct genl_info *info);
+int ieee802154_scan_req(struct sk_buff *skb, struct genl_info *info);
+int ieee802154_start_req(struct sk_buff *skb, struct genl_info *info);
+int ieee802154_list_iface(struct sk_buff *skb, struct genl_info *info);
+int ieee802154_dump_iface(struct sk_buff *skb, struct netlink_callback *cb);
 
 #endif
diff --git a/net/ieee802154/netlink.c b/net/ieee802154/netlink.c
index 7e49bbc..eb9faef 100644
--- a/net/ieee802154/netlink.c
+++ b/net/ieee802154/netlink.c
@@ -109,24 +109,39 @@ out:
 	return -ENOBUFS;
 }
 
+static struct genl_ops ieee8021154_ops[] = {
+	/* see nl-phy.c */
+	IEEE802154_DUMP(IEEE802154_LIST_PHY, ieee802154_list_phy,
+			ieee802154_dump_phy),
+	IEEE802154_OP(IEEE802154_ADD_IFACE, ieee802154_add_iface),
+	IEEE802154_OP(IEEE802154_DEL_IFACE, ieee802154_del_iface),
+	/* see nl-mac.c */
+	IEEE802154_OP(IEEE802154_ASSOCIATE_REQ, ieee802154_associate_req),
+	IEEE802154_OP(IEEE802154_ASSOCIATE_RESP, ieee802154_associate_resp),
+	IEEE802154_OP(IEEE802154_DISASSOCIATE_REQ, ieee802154_disassociate_req),
+	IEEE802154_OP(IEEE802154_SCAN_REQ, ieee802154_scan_req),
+	IEEE802154_OP(IEEE802154_START_REQ, ieee802154_start_req),
+	IEEE802154_DUMP(IEEE802154_LIST_IFACE, ieee802154_list_iface,
+			ieee802154_dump_iface),
+};
+
 int __init ieee802154_nl_init(void)
 {
 	int rc;
 
-	rc = genl_register_family(&nl802154_family);
+	rc = genl_register_family_with_ops(&nl802154_family, ieee8021154_ops,
+					   ARRAY_SIZE(ieee8021154_ops));
 	if (rc)
-		goto fail;
+		return rc;
 
-	rc = nl802154_mac_register();
+	rc = genl_register_mc_group(&nl802154_family, &ieee802154_coord_mcgrp);
 	if (rc)
 		goto fail;
 
-	rc = nl802154_phy_register();
+	rc = genl_register_mc_group(&nl802154_family, &ieee802154_beacon_mcgrp);
 	if (rc)
 		goto fail;
-
 	return 0;
-
 fail:
 	genl_unregister_family(&nl802154_family);
 	return rc;
@@ -136,4 +151,3 @@ void __exit ieee802154_nl_exit(void)
 {
 	genl_unregister_family(&nl802154_family);
 }
-
diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c
index b0bdd8c..28d4930 100644
--- a/net/ieee802154/nl-mac.c
+++ b/net/ieee802154/nl-mac.c
@@ -39,11 +39,11 @@
 
 #include "ieee802154.h"
 
-static struct genl_multicast_group ieee802154_coord_mcgrp = {
+struct genl_multicast_group ieee802154_coord_mcgrp = {
 	.name		= IEEE802154_MCAST_COORD_NAME,
 };
 
-static struct genl_multicast_group ieee802154_beacon_mcgrp = {
+struct genl_multicast_group ieee802154_beacon_mcgrp = {
 	.name		= IEEE802154_MCAST_BEACON_NAME,
 };
 
@@ -309,8 +309,7 @@ static struct net_device *ieee802154_nl_get_dev(struct genl_info *info)
 	return dev;
 }
 
-static int ieee802154_associate_req(struct sk_buff *skb,
-		struct genl_info *info)
+int ieee802154_associate_req(struct sk_buff *skb, struct genl_info *info)
 {
 	struct net_device *dev;
 	struct ieee802154_addr addr;
@@ -357,8 +356,7 @@ out:
 	return ret;
 }
 
-static int ieee802154_associate_resp(struct sk_buff *skb,
-		struct genl_info *info)
+int ieee802154_associate_resp(struct sk_buff *skb, struct genl_info *info)
 {
 	struct net_device *dev;
 	struct ieee802154_addr addr;
@@ -390,8 +388,7 @@ out:
 	return ret;
 }
 
-static int ieee802154_disassociate_req(struct sk_buff *skb,
-		struct genl_info *info)
+int ieee802154_disassociate_req(struct sk_buff *skb, struct genl_info *info)
 {
 	struct net_device *dev;
 	struct ieee802154_addr addr;
@@ -433,7 +430,7 @@ out:
  * PAN_coordinator, battery_life_extension = 0,
  * coord_realignment = 0, security_enable = 0
 */
-static int ieee802154_start_req(struct sk_buff *skb, struct genl_info *info)
+int ieee802154_start_req(struct sk_buff *skb, struct genl_info *info)
 {
 	struct net_device *dev;
 	struct ieee802154_addr addr;
@@ -492,7 +489,7 @@ out:
 	return ret;
 }
 
-static int ieee802154_scan_req(struct sk_buff *skb, struct genl_info *info)
+int ieee802154_scan_req(struct sk_buff *skb, struct genl_info *info)
 {
 	struct net_device *dev;
 	int ret = -EOPNOTSUPP;
@@ -530,8 +527,7 @@ out:
 	return ret;
 }
 
-static int ieee802154_list_iface(struct sk_buff *skb,
-	struct genl_info *info)
+int ieee802154_list_iface(struct sk_buff *skb, struct genl_info *info)
 {
 	/* Request for interface name, index, type, IEEE address,
 	   PAN Id, short address */
@@ -565,8 +561,7 @@ out_dev:
 
 }
 
-static int ieee802154_dump_iface(struct sk_buff *skb,
-	struct netlink_callback *cb)
+int ieee802154_dump_iface(struct sk_buff *skb, struct netlink_callback *cb)
 {
 	struct net *net = sock_net(skb->sk);
 	struct net_device *dev;
@@ -590,41 +585,3 @@ cont:
 
 	return skb->len;
 }
-
-static struct genl_ops ieee802154_coordinator_ops[] = {
-	IEEE802154_OP(IEEE802154_ASSOCIATE_REQ, ieee802154_associate_req),
-	IEEE802154_OP(IEEE802154_ASSOCIATE_RESP, ieee802154_associate_resp),
-	IEEE802154_OP(IEEE802154_DISASSOCIATE_REQ, ieee802154_disassociate_req),
-	IEEE802154_OP(IEEE802154_SCAN_REQ, ieee802154_scan_req),
-	IEEE802154_OP(IEEE802154_START_REQ, ieee802154_start_req),
-	IEEE802154_DUMP(IEEE802154_LIST_IFACE, ieee802154_list_iface,
-							ieee802154_dump_iface),
-};
-
-/*
- * No need to unregister as family unregistration will do it.
- */
-int nl802154_mac_register(void)
-{
-	int i;
-	int rc;
-
-	rc = genl_register_mc_group(&nl802154_family,
-			&ieee802154_coord_mcgrp);
-	if (rc)
-		return rc;
-
-	rc = genl_register_mc_group(&nl802154_family,
-			&ieee802154_beacon_mcgrp);
-	if (rc)
-		return rc;
-
-	for (i = 0; i < ARRAY_SIZE(ieee802154_coordinator_ops); i++) {
-		rc = genl_register_ops(&nl802154_family,
-				&ieee802154_coordinator_ops[i]);
-		if (rc)
-			return rc;
-	}
-
-	return 0;
-}
diff --git a/net/ieee802154/nl-phy.c b/net/ieee802154/nl-phy.c
index 22b1a70..d08c7a4 100644
--- a/net/ieee802154/nl-phy.c
+++ b/net/ieee802154/nl-phy.c
@@ -77,8 +77,7 @@ out:
 	return -EMSGSIZE;
 }
 
-static int ieee802154_list_phy(struct sk_buff *skb,
-	struct genl_info *info)
+int ieee802154_list_phy(struct sk_buff *skb, struct genl_info *info)
 {
 	/* Request for interface name, index, type, IEEE address,
 	   PAN Id, short address */
@@ -151,8 +150,7 @@ static int ieee802154_dump_phy_iter(struct wpan_phy *phy, void *_data)
 	return 0;
 }
 
-static int ieee802154_dump_phy(struct sk_buff *skb,
-	struct netlink_callback *cb)
+int ieee802154_dump_phy(struct sk_buff *skb, struct netlink_callback *cb)
 {
 	struct dump_phy_data data = {
 		.cb = cb,
@@ -170,8 +168,7 @@ static int ieee802154_dump_phy(struct sk_buff *skb,
 	return skb->len;
 }
 
-static int ieee802154_add_iface(struct sk_buff *skb,
-		struct genl_info *info)
+int ieee802154_add_iface(struct sk_buff *skb, struct genl_info *info)
 {
 	struct sk_buff *msg;
 	struct wpan_phy *phy;
@@ -273,8 +270,7 @@ out_dev:
 	return rc;
 }
 
-static int ieee802154_del_iface(struct sk_buff *skb,
-		struct genl_info *info)
+int ieee802154_del_iface(struct sk_buff *skb, struct genl_info *info)
 {
 	struct sk_buff *msg;
 	struct wpan_phy *phy;
@@ -356,28 +352,3 @@ out_dev:
 
 	return rc;
 }
-
-static struct genl_ops ieee802154_phy_ops[] = {
-	IEEE802154_DUMP(IEEE802154_LIST_PHY, ieee802154_list_phy,
-							ieee802154_dump_phy),
-	IEEE802154_OP(IEEE802154_ADD_IFACE, ieee802154_add_iface),
-	IEEE802154_OP(IEEE802154_DEL_IFACE, ieee802154_del_iface),
-};
-
-/*
- * No need to unregister as family unregistration will do it.
- */
-int nl802154_phy_register(void)
-{
-	int i;
-	int rc;
-
-	for (i = 0; i < ARRAY_SIZE(ieee802154_phy_ops); i++) {
-		rc = genl_register_ops(&nl802154_family,
-				&ieee802154_phy_ops[i]);
-		if (rc)
-			return rc;
-	}
-
-	return 0;
-}
-- 
1.8.4.rc3

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [RFC 4/7] wimax: use genl_register_family_with_ops()
  2013-11-14  9:14 [RFC 0/7] genetlink: reduce ops size and complexity Johannes Berg
                   ` (2 preceding siblings ...)
  2013-11-14  9:14 ` [RFC 3/7] ieee802154: " Johannes Berg
@ 2013-11-14  9:14 ` Johannes Berg
  2013-11-14  9:14 ` [RFC 5/7] genetlink: remove genl_register_ops/genl_unregister_ops Johannes Berg
                   ` (7 subsequent siblings)
  11 siblings, 0 replies; 29+ messages in thread
From: Johannes Berg @ 2013-11-14  9:14 UTC (permalink / raw)
  To: netdev; +Cc: Johannes Berg

From: Johannes Berg <johannes.berg@intel.com>

This simplifies the code since there's no longer a need to
have error handling in the registration.

Unfortunately it means more extern function declarations are
needed, but the overall goal would seem to justify this.

Due to the removal of duplication in the netlink policies,
this reduces the size of wimax by almost 1k.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 net/wimax/op-msg.c         | 25 ---------------
 net/wimax/op-reset.c       | 17 ----------
 net/wimax/op-rfkill.c      | 21 ------------
 net/wimax/op-state-get.c   | 17 ----------
 net/wimax/stack.c          | 79 +++++++++++++++++++++++-----------------------
 net/wimax/wimax-internal.h |  7 ++++
 6 files changed, 47 insertions(+), 119 deletions(-)

diff --git a/net/wimax/op-msg.c b/net/wimax/op-msg.c
index 0694d62..ff19cbe 100644
--- a/net/wimax/op-msg.c
+++ b/net/wimax/op-msg.c
@@ -321,17 +321,6 @@ int wimax_msg(struct wimax_dev *wimax_dev, const char *pipe_name,
 }
 EXPORT_SYMBOL_GPL(wimax_msg);
 
-
-static const struct nla_policy wimax_gnl_msg_policy[WIMAX_GNL_ATTR_MAX + 1] = {
-	[WIMAX_GNL_MSG_IFIDX] = {
-		.type = NLA_U32,
-	},
-	[WIMAX_GNL_MSG_DATA] = {
-		.type = NLA_UNSPEC,	/* libnl doesn't grok BINARY yet */
-	},
-};
-
-
 /*
  * Relays a message from user space to the driver
  *
@@ -340,7 +329,6 @@ static const struct nla_policy wimax_gnl_msg_policy[WIMAX_GNL_ATTR_MAX + 1] = {
  *
  * This call will block while handling/relaying the message.
  */
-static
 int wimax_gnl_doit_msg_from_user(struct sk_buff *skb, struct genl_info *info)
 {
 	int result, ifindex;
@@ -418,16 +406,3 @@ error_no_wimax_dev:
 	return result;
 }
 
-
-/*
- * Generic Netlink glue
- */
-
-struct genl_ops wimax_gnl_msg_from_user = {
-	.cmd = WIMAX_GNL_OP_MSG_FROM_USER,
-	.flags = GENL_ADMIN_PERM,
-	.policy = wimax_gnl_msg_policy,
-	.doit = wimax_gnl_doit_msg_from_user,
-	.dumpit = NULL,
-};
-
diff --git a/net/wimax/op-reset.c b/net/wimax/op-reset.c
index 7ceffe3..eb45807 100644
--- a/net/wimax/op-reset.c
+++ b/net/wimax/op-reset.c
@@ -92,13 +92,6 @@ int wimax_reset(struct wimax_dev *wimax_dev)
 EXPORT_SYMBOL(wimax_reset);
 
 
-static const struct nla_policy wimax_gnl_reset_policy[WIMAX_GNL_ATTR_MAX + 1] = {
-	[WIMAX_GNL_RESET_IFIDX] = {
-		.type = NLA_U32,
-	},
-};
-
-
 /*
  * Exporting to user space over generic netlink
  *
@@ -106,7 +99,6 @@ static const struct nla_policy wimax_gnl_reset_policy[WIMAX_GNL_ATTR_MAX + 1] =
  *
  * No attributes.
  */
-static
 int wimax_gnl_doit_reset(struct sk_buff *skb, struct genl_info *info)
 {
 	int result, ifindex;
@@ -130,12 +122,3 @@ error_no_wimax_dev:
 	d_fnend(3, NULL, "(skb %p info %p) = %d\n", skb, info, result);
 	return result;
 }
-
-
-struct genl_ops wimax_gnl_reset = {
-	.cmd = WIMAX_GNL_OP_RESET,
-	.flags = GENL_ADMIN_PERM,
-	.policy = wimax_gnl_reset_policy,
-	.doit = wimax_gnl_doit_reset,
-	.dumpit = NULL,
-};
diff --git a/net/wimax/op-rfkill.c b/net/wimax/op-rfkill.c
index 7ab60ba..403078d 100644
--- a/net/wimax/op-rfkill.c
+++ b/net/wimax/op-rfkill.c
@@ -411,17 +411,6 @@ void wimax_rfkill_rm(struct wimax_dev *wimax_dev)
  * just query).
  */
 
-static const struct nla_policy wimax_gnl_rfkill_policy[WIMAX_GNL_ATTR_MAX + 1] = {
-	[WIMAX_GNL_RFKILL_IFIDX] = {
-		.type = NLA_U32,
-	},
-	[WIMAX_GNL_RFKILL_STATE] = {
-		.type = NLA_U32		/* enum wimax_rf_state */
-	},
-};
-
-
-static
 int wimax_gnl_doit_rfkill(struct sk_buff *skb, struct genl_info *info)
 {
 	int result, ifindex;
@@ -457,13 +446,3 @@ error_no_wimax_dev:
 	d_fnend(3, NULL, "(skb %p info %p) = %d\n", skb, info, result);
 	return result;
 }
-
-
-struct genl_ops wimax_gnl_rfkill = {
-	.cmd = WIMAX_GNL_OP_RFKILL,
-	.flags = GENL_ADMIN_PERM,
-	.policy = wimax_gnl_rfkill_policy,
-	.doit = wimax_gnl_doit_rfkill,
-	.dumpit = NULL,
-};
-
diff --git a/net/wimax/op-state-get.c b/net/wimax/op-state-get.c
index aff8776..995c08c 100644
--- a/net/wimax/op-state-get.c
+++ b/net/wimax/op-state-get.c
@@ -33,13 +33,6 @@
 #include "debug-levels.h"
 
 
-static const struct nla_policy wimax_gnl_state_get_policy[WIMAX_GNL_ATTR_MAX + 1] = {
-	[WIMAX_GNL_STGET_IFIDX] = {
-		.type = NLA_U32,
-	},
-};
-
-
 /*
  * Exporting to user space over generic netlink
  *
@@ -48,7 +41,6 @@ static const struct nla_policy wimax_gnl_state_get_policy[WIMAX_GNL_ATTR_MAX + 1
  *
  * No attributes.
  */
-static
 int wimax_gnl_doit_state_get(struct sk_buff *skb, struct genl_info *info)
 {
 	int result, ifindex;
@@ -72,12 +64,3 @@ error_no_wimax_dev:
 	d_fnend(3, NULL, "(skb %p info %p) = %d\n", skb, info, result);
 	return result;
 }
-
-
-struct genl_ops wimax_gnl_state_get = {
-	.cmd = WIMAX_GNL_OP_STATE_GET,
-	.flags = GENL_ADMIN_PERM,
-	.policy = wimax_gnl_state_get_policy,
-	.doit = wimax_gnl_doit_state_get,
-	.dumpit = NULL,
-};
diff --git a/net/wimax/stack.c b/net/wimax/stack.c
index a6470ac..4b7f15a 100644
--- a/net/wimax/stack.c
+++ b/net/wimax/stack.c
@@ -402,22 +402,44 @@ void wimax_dev_init(struct wimax_dev *wimax_dev)
 }
 EXPORT_SYMBOL_GPL(wimax_dev_init);
 
-/*
- * This extern is declared here because it's easier to keep track --
- * both declarations are a list of the same
- */
-extern struct genl_ops
-	wimax_gnl_msg_from_user,
-	wimax_gnl_reset,
-	wimax_gnl_rfkill,
-	wimax_gnl_state_get;
+static const struct nla_policy wimax_gnl_policy[WIMAX_GNL_ATTR_MAX + 1] = {
+	[WIMAX_GNL_RESET_IFIDX] = { .type = NLA_U32, },
+	[WIMAX_GNL_RFKILL_IFIDX] = { .type = NLA_U32, },
+	[WIMAX_GNL_RFKILL_STATE] = {
+		.type = NLA_U32		/* enum wimax_rf_state */
+	},
+	[WIMAX_GNL_STGET_IFIDX] = { .type = NLA_U32, },
+	[WIMAX_GNL_MSG_IFIDX] = { .type = NLA_U32, },
+	[WIMAX_GNL_MSG_DATA] = {
+		.type = NLA_UNSPEC,	/* libnl doesn't grok BINARY yet */
+	},
+};
 
-static
-struct genl_ops *wimax_gnl_ops[] = {
-	&wimax_gnl_msg_from_user,
-	&wimax_gnl_reset,
-	&wimax_gnl_rfkill,
-	&wimax_gnl_state_get,
+static struct genl_ops wimax_gnl_ops[] = {
+	{
+		.cmd = WIMAX_GNL_OP_MSG_FROM_USER,
+		.flags = GENL_ADMIN_PERM,
+		.policy = wimax_gnl_policy,
+		.doit = wimax_gnl_doit_msg_from_user,
+	},
+	{
+		.cmd = WIMAX_GNL_OP_RESET,
+		.flags = GENL_ADMIN_PERM,
+		.policy = wimax_gnl_policy,
+		.doit = wimax_gnl_doit_reset,
+	},
+	{
+		.cmd = WIMAX_GNL_OP_RFKILL,
+		.flags = GENL_ADMIN_PERM,
+		.policy = wimax_gnl_policy,
+		.doit = wimax_gnl_doit_rfkill,
+	},
+	{
+		.cmd = WIMAX_GNL_OP_STATE_GET,
+		.flags = GENL_ADMIN_PERM,
+		.policy = wimax_gnl_policy,
+		.doit = wimax_gnl_doit_state_get,
+	},
 };
 
 
@@ -567,7 +589,7 @@ struct genl_multicast_group wimax_gnl_mcg = {
 static
 int __init wimax_subsys_init(void)
 {
-	int result, cnt;
+	int result;
 
 	d_fnstart(4, NULL, "()\n");
 	d_parse_params(D_LEVEL, D_LEVEL_SIZE, wimax_debug_params,
@@ -575,26 +597,14 @@ int __init wimax_subsys_init(void)
 
 	snprintf(wimax_gnl_family.name, sizeof(wimax_gnl_family.name),
 		 "WiMAX");
-	result = genl_register_family(&wimax_gnl_family);
+	result = genl_register_family_with_ops(&wimax_gnl_family, wimax_gnl_ops,
+					       ARRAY_SIZE(wimax_gnl_ops));
 	if (unlikely(result < 0)) {
 		printk(KERN_ERR "cannot register generic netlink family: %d\n",
 		       result);
 		goto error_register_family;
 	}
 
-	for (cnt = 0; cnt < ARRAY_SIZE(wimax_gnl_ops); cnt++) {
-		result = genl_register_ops(&wimax_gnl_family,
-					   wimax_gnl_ops[cnt]);
-		d_printf(4, NULL, "registering generic netlink op code "
-			 "%u: %d\n", wimax_gnl_ops[cnt]->cmd, result);
-		if (unlikely(result < 0)) {
-			printk(KERN_ERR "cannot register generic netlink op "
-			       "code %u: %d\n",
-			       wimax_gnl_ops[cnt]->cmd, result);
-			goto error_register_ops;
-		}
-	}
-
 	result = genl_register_mc_group(&wimax_gnl_family, &wimax_gnl_mcg);
 	if (result < 0)
 		goto error_mc_group;
@@ -602,10 +612,6 @@ int __init wimax_subsys_init(void)
 	return 0;
 
 error_mc_group:
-error_register_ops:
-	for (cnt--; cnt >= 0; cnt--)
-		genl_unregister_ops(&wimax_gnl_family,
-				    wimax_gnl_ops[cnt]);
 	genl_unregister_family(&wimax_gnl_family);
 error_register_family:
 	d_fnend(4, NULL, "() = %d\n", result);
@@ -619,12 +625,7 @@ module_init(wimax_subsys_init);
 static
 void __exit wimax_subsys_exit(void)
 {
-	int cnt;
 	wimax_id_table_release();
-	genl_unregister_mc_group(&wimax_gnl_family, &wimax_gnl_mcg);
-	for (cnt = ARRAY_SIZE(wimax_gnl_ops) - 1; cnt >= 0; cnt--)
-		genl_unregister_ops(&wimax_gnl_family,
-				    wimax_gnl_ops[cnt]);
 	genl_unregister_family(&wimax_gnl_family);
 }
 module_exit(wimax_subsys_exit);
diff --git a/net/wimax/wimax-internal.h b/net/wimax/wimax-internal.h
index 5dcd9c0..8567d30 100644
--- a/net/wimax/wimax-internal.h
+++ b/net/wimax/wimax-internal.h
@@ -84,8 +84,15 @@ void wimax_id_table_release(void);
 int wimax_rfkill_add(struct wimax_dev *);
 void wimax_rfkill_rm(struct wimax_dev *);
 
+/* generic netlink */
 extern struct genl_family wimax_gnl_family;
 extern struct genl_multicast_group wimax_gnl_mcg;
 
+/* ops */
+int wimax_gnl_doit_msg_from_user(struct sk_buff *skb, struct genl_info *info);
+int wimax_gnl_doit_reset(struct sk_buff *skb, struct genl_info *info);
+int wimax_gnl_doit_rfkill(struct sk_buff *skb, struct genl_info *info);
+int wimax_gnl_doit_state_get(struct sk_buff *skb, struct genl_info *info);
+
 #endif /* #ifdef __KERNEL__ */
 #endif /* #ifndef __WIMAX_INTERNAL_H__ */
-- 
1.8.4.rc3

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [RFC 5/7] genetlink: remove genl_register_ops/genl_unregister_ops
  2013-11-14  9:14 [RFC 0/7] genetlink: reduce ops size and complexity Johannes Berg
                   ` (3 preceding siblings ...)
  2013-11-14  9:14 ` [RFC 4/7] wimax: " Johannes Berg
@ 2013-11-14  9:14 ` Johannes Berg
  2013-11-14  9:14 ` [RFC 6/7] genetlink: register family ops as array Johannes Berg
                   ` (6 subsequent siblings)
  11 siblings, 0 replies; 29+ messages in thread
From: Johannes Berg @ 2013-11-14  9:14 UTC (permalink / raw)
  To: netdev; +Cc: Johannes Berg

From: Johannes Berg <johannes.berg@intel.com>

genl_register_ops() is still needed for internal registration,
but is no longer available to users of the API.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 include/net/genetlink.h |  2 --
 net/netlink/genetlink.c | 57 +------------------------------------------------
 2 files changed, 1 insertion(+), 58 deletions(-)

diff --git a/include/net/genetlink.h b/include/net/genetlink.h
index 9b787b6..617d718 100644
--- a/include/net/genetlink.h
+++ b/include/net/genetlink.h
@@ -141,8 +141,6 @@ static inline int genl_register_family_with_ops(struct genl_family *family,
 }
 
 int genl_unregister_family(struct genl_family *family);
-int genl_register_ops(struct genl_family *, struct genl_ops *ops);
-int genl_unregister_ops(struct genl_family *, struct genl_ops *ops);
 int genl_register_mc_group(struct genl_family *family,
 			   struct genl_multicast_group *grp);
 void genl_unregister_mc_group(struct genl_family *family,
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index 0c741ce..fbccb45 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -283,22 +283,7 @@ static void genl_unregister_mc_groups(struct genl_family *family)
 		__genl_unregister_mc_group(family, grp);
 }
 
-/**
- * genl_register_ops - register generic netlink operations
- * @family: generic netlink family
- * @ops: operations to be registered
- *
- * Registers the specified operations and assigns them to the specified
- * family. Either a doit or dumpit callback must be specified or the
- * operation will fail. Only one operation structure per command
- * identifier may be registered.
- *
- * See include/net/genetlink.h for more documenation on the operations
- * structure.
- *
- * Returns 0 on success or a negative error code.
- */
-int genl_register_ops(struct genl_family *family, struct genl_ops *ops)
+static int genl_register_ops(struct genl_family *family, struct genl_ops *ops)
 {
 	int err = -EINVAL;
 
@@ -326,42 +311,6 @@ int genl_register_ops(struct genl_family *family, struct genl_ops *ops)
 errout:
 	return err;
 }
-EXPORT_SYMBOL(genl_register_ops);
-
-/**
- * genl_unregister_ops - unregister generic netlink operations
- * @family: generic netlink family
- * @ops: operations to be unregistered
- *
- * Unregisters the specified operations and unassigns them from the
- * specified family. The operation blocks until the current message
- * processing has finished and doesn't start again until the
- * unregister process has finished.
- *
- * Note: It is not necessary to unregister all operations before
- *       unregistering the family, unregistering the family will cause
- *       all assigned operations to be unregistered automatically.
- *
- * Returns 0 on success or a negative error code.
- */
-int genl_unregister_ops(struct genl_family *family, struct genl_ops *ops)
-{
-	struct genl_ops *rc;
-
-	genl_lock_all();
-	list_for_each_entry(rc, &family->ops_list, ops_list) {
-		if (rc == ops) {
-			list_del(&ops->ops_list);
-			genl_unlock_all();
-			genl_ctrl_event(CTRL_CMD_DELOPS, ops);
-			return 0;
-		}
-	}
-	genl_unlock_all();
-
-	return -ENOENT;
-}
-EXPORT_SYMBOL(genl_unregister_ops);
 
 /**
  * __genl_register_family - register a generic netlink family
@@ -451,10 +400,6 @@ EXPORT_SYMBOL(__genl_register_family);
  * See include/net/genetlink.h for more documenation on the operations
  * structure.
  *
- * This is equivalent to calling genl_register_family() followed by
- * genl_register_ops() for every operation entry in the table taking
- * care to unregister the family on error path.
- *
  * Return 0 on success or a negative error code.
  */
 int __genl_register_family_with_ops(struct genl_family *family,
-- 
1.8.4.rc3

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [RFC 6/7] genetlink: register family ops as array
  2013-11-14  9:14 [RFC 0/7] genetlink: reduce ops size and complexity Johannes Berg
                   ` (4 preceding siblings ...)
  2013-11-14  9:14 ` [RFC 5/7] genetlink: remove genl_register_ops/genl_unregister_ops Johannes Berg
@ 2013-11-14  9:14 ` Johannes Berg
  2013-11-14  9:14 ` [RFC 7/7] genetlink: allow making ops const Johannes Berg
                   ` (5 subsequent siblings)
  11 siblings, 0 replies; 29+ messages in thread
From: Johannes Berg @ 2013-11-14  9:14 UTC (permalink / raw)
  To: netdev; +Cc: Johannes Berg

From: Johannes Berg <johannes.berg@intel.com>

Instead of using a linked list, use an array. This reduces
the data size needed by the users of genetlink, for example
in wireless (net/wireless/nl80211.c) on 64-bit it frees up
over 1K of data space.

Remove the attempted sending of CTRL_CMD_NEWOPS ctrl event
since genl_ctrl_event(CTRL_CMD_NEWOPS, ...) only returns
-EINVAL anyway, therefore no such event could ever be sent.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 include/net/genetlink.h |  5 ++--
 net/netlink/genetlink.c | 71 ++++++++++++++++++++++---------------------------
 2 files changed, 34 insertions(+), 42 deletions(-)

diff --git a/include/net/genetlink.h b/include/net/genetlink.h
index 617d718..abd4146 100644
--- a/include/net/genetlink.h
+++ b/include/net/genetlink.h
@@ -39,7 +39,6 @@ struct genl_info;
  * @post_doit: called after an operation's doit callback, it may
  *	undo operations done by pre_doit, for example release locks
  * @attrbuf: buffer to store parsed attributes
- * @ops_list: list of all assigned operations
  * @family_list: family list
  * @mcast_groups: multicast groups list
  */
@@ -58,7 +57,8 @@ struct genl_family {
 					     struct sk_buff *skb,
 					     struct genl_info *info);
 	struct nlattr **	attrbuf;	/* private */
-	struct list_head	ops_list;	/* private */
+	struct genl_ops *	ops;
+	unsigned int		n_ops;
 	struct list_head	family_list;	/* private */
 	struct list_head	mcast_groups;	/* private */
 	struct module		*module;
@@ -119,7 +119,6 @@ struct genl_ops {
 	int		       (*dumpit)(struct sk_buff *skb,
 					 struct netlink_callback *cb);
 	int		       (*done)(struct netlink_callback *cb);
-	struct list_head	ops_list;
 };
 
 int __genl_register_family(struct genl_family *family);
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index fbccb45..d5a7f98 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -109,9 +109,10 @@ static struct genl_family *genl_family_find_byname(char *name)
 static struct genl_ops *genl_get_cmd(u8 cmd, struct genl_family *family)
 {
 	struct genl_ops *ops;
+	unsigned int i;
 
-	list_for_each_entry(ops, &family->ops_list, ops_list)
-		if (ops->cmd == cmd)
+	for (i = 0; i < family->n_ops; i++)
+		if (family->ops[i].cmd == cmd)
 			return ops;
 
 	return NULL;
@@ -283,32 +284,33 @@ static void genl_unregister_mc_groups(struct genl_family *family)
 		__genl_unregister_mc_group(family, grp);
 }
 
-static int genl_register_ops(struct genl_family *family, struct genl_ops *ops)
+static int genl_validate_add_ops(struct genl_family *family, struct genl_ops *ops,
+				 unsigned int n_ops)
 {
+	int i, j;
 	int err = -EINVAL;
 
-	if (ops->dumpit == NULL && ops->doit == NULL)
-		goto errout;
+	for (i = 0; i < n_ops; i++)
+		if (ops[i].dumpit == NULL && ops[i].doit == NULL)
+			return -EINVAL;
 
-	if (genl_get_cmd(ops->cmd, family)) {
-		err = -EEXIST;
-		goto errout;
+	for (i = 0; i < n_ops; i++) {
+		for (j = i; j < n_ops; j++) {
+			if (ops[i].cmd == ops[j].cmd)
+				return -EINVAL;
+		}
+		if (ops[i].dumpit)
+			ops[i].flags |= GENL_CMD_CAP_DUMP;
+		if (ops[i].doit)
+			ops[i].flags |= GENL_CMD_CAP_DO;
+		if (ops[i].policy)
+			ops[i].flags |= GENL_CMD_CAP_HASPOL;
 	}
 
-	if (ops->dumpit)
-		ops->flags |= GENL_CMD_CAP_DUMP;
-	if (ops->doit)
-		ops->flags |= GENL_CMD_CAP_DO;
-	if (ops->policy)
-		ops->flags |= GENL_CMD_CAP_HASPOL;
+	/* family is not registered yet, so no locking needed */
+	family->ops = ops;
+	family->n_ops = n_ops;
 
-	genl_lock_all();
-	list_add_tail(&ops->ops_list, &family->ops_list);
-	genl_unlock_all();
-
-	genl_ctrl_event(CTRL_CMD_NEWOPS, ops);
-	err = 0;
-errout:
 	return err;
 }
 
@@ -333,7 +335,6 @@ int __genl_register_family(struct genl_family *family)
 	if (family->id > GENL_MAX_ID)
 		goto errout;
 
-	INIT_LIST_HEAD(&family->ops_list);
 	INIT_LIST_HEAD(&family->mcast_groups);
 
 	genl_lock_all();
@@ -405,21 +406,13 @@ EXPORT_SYMBOL(__genl_register_family);
 int __genl_register_family_with_ops(struct genl_family *family,
 	struct genl_ops *ops, size_t n_ops)
 {
-	int err, i;
+	int err;
 
-	err = __genl_register_family(family);
+	err = genl_validate_add_ops(family, ops, n_ops);
 	if (err)
 		return err;
 
-	for (i = 0; i < n_ops; ++i, ++ops) {
-		err = genl_register_ops(family, ops);
-		if (err)
-			goto err_out;
-	}
-	return 0;
-err_out:
-	genl_unregister_family(family);
-	return err;
+	return __genl_register_family(family);
 }
 EXPORT_SYMBOL(__genl_register_family_with_ops);
 
@@ -444,7 +437,7 @@ int genl_unregister_family(struct genl_family *family)
 			continue;
 
 		list_del(&rc->family_list);
-		INIT_LIST_HEAD(&family->ops_list);
+		family->n_ops = 0;
 		genl_unlock_all();
 
 		kfree(family->attrbuf);
@@ -671,19 +664,19 @@ static int ctrl_fill_info(struct genl_family *family, u32 portid, u32 seq,
 	    nla_put_u32(skb, CTRL_ATTR_MAXATTR, family->maxattr))
 		goto nla_put_failure;
 
-	if (!list_empty(&family->ops_list)) {
+	if (family->n_ops) {
 		struct nlattr *nla_ops;
-		struct genl_ops *ops;
-		int idx = 1;
+		int i;
 
 		nla_ops = nla_nest_start(skb, CTRL_ATTR_OPS);
 		if (nla_ops == NULL)
 			goto nla_put_failure;
 
-		list_for_each_entry(ops, &family->ops_list, ops_list) {
+		for (i = 0; i < family->n_ops; i++) {
 			struct nlattr *nest;
+			struct genl_ops *ops = &family->ops[i];
 
-			nest = nla_nest_start(skb, idx++);
+			nest = nla_nest_start(skb, i + 1);
 			if (nest == NULL)
 				goto nla_put_failure;
 
-- 
1.8.4.rc3

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [RFC 7/7] genetlink: allow making ops const
  2013-11-14  9:14 [RFC 0/7] genetlink: reduce ops size and complexity Johannes Berg
                   ` (5 preceding siblings ...)
  2013-11-14  9:14 ` [RFC 6/7] genetlink: register family ops as array Johannes Berg
@ 2013-11-14  9:14 ` Johannes Berg
  2013-11-14 13:41 ` [RFC 8/7] genetlink: make all genl_ops users const Johannes Berg
                   ` (4 subsequent siblings)
  11 siblings, 0 replies; 29+ messages in thread
From: Johannes Berg @ 2013-11-14  9:14 UTC (permalink / raw)
  To: netdev; +Cc: Johannes Berg

From: Johannes Berg <johannes.berg@intel.com>

Allow making the ops array const by not modifying the ops
flags on registration but rather only when ops are sent
out in the family information.

No users are updated yet.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 include/net/genetlink.h |  6 +++---
 net/netlink/genetlink.c | 23 +++++++++++++----------
 2 files changed, 16 insertions(+), 13 deletions(-)

diff --git a/include/net/genetlink.h b/include/net/genetlink.h
index abd4146..0b6b10b 100644
--- a/include/net/genetlink.h
+++ b/include/net/genetlink.h
@@ -57,7 +57,7 @@ struct genl_family {
 					     struct sk_buff *skb,
 					     struct genl_info *info);
 	struct nlattr **	attrbuf;	/* private */
-	struct genl_ops *	ops;
+	const struct genl_ops *	ops;
 	unsigned int		n_ops;
 	struct list_head	family_list;	/* private */
 	struct list_head	mcast_groups;	/* private */
@@ -130,10 +130,10 @@ static inline int genl_register_family(struct genl_family *family)
 }
 
 int __genl_register_family_with_ops(struct genl_family *family,
-				    struct genl_ops *ops, size_t n_ops);
+				    const struct genl_ops *ops, size_t n_ops);
 
 static inline int genl_register_family_with_ops(struct genl_family *family,
-	struct genl_ops *ops, size_t n_ops)
+	const struct genl_ops *ops, size_t n_ops)
 {
 	family->module = THIS_MODULE;
 	return __genl_register_family_with_ops(family, ops, n_ops);
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index d5a7f98..3ad151f 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -284,7 +284,8 @@ static void genl_unregister_mc_groups(struct genl_family *family)
 		__genl_unregister_mc_group(family, grp);
 }
 
-static int genl_validate_add_ops(struct genl_family *family, struct genl_ops *ops,
+static int genl_validate_add_ops(struct genl_family *family,
+				 const struct genl_ops *ops,
 				 unsigned int n_ops)
 {
 	int i, j;
@@ -299,12 +300,6 @@ static int genl_validate_add_ops(struct genl_family *family, struct genl_ops *op
 			if (ops[i].cmd == ops[j].cmd)
 				return -EINVAL;
 		}
-		if (ops[i].dumpit)
-			ops[i].flags |= GENL_CMD_CAP_DUMP;
-		if (ops[i].doit)
-			ops[i].flags |= GENL_CMD_CAP_DO;
-		if (ops[i].policy)
-			ops[i].flags |= GENL_CMD_CAP_HASPOL;
 	}
 
 	/* family is not registered yet, so no locking needed */
@@ -404,7 +399,7 @@ EXPORT_SYMBOL(__genl_register_family);
  * Return 0 on success or a negative error code.
  */
 int __genl_register_family_with_ops(struct genl_family *family,
-	struct genl_ops *ops, size_t n_ops)
+	const struct genl_ops *ops, size_t n_ops)
 {
 	int err;
 
@@ -674,14 +669,22 @@ static int ctrl_fill_info(struct genl_family *family, u32 portid, u32 seq,
 
 		for (i = 0; i < family->n_ops; i++) {
 			struct nlattr *nest;
-			struct genl_ops *ops = &family->ops[i];
+			const struct genl_ops *ops = &family->ops[i];
+			u32 flags = ops->flags;
+
+			if (ops->dumpit)
+				flags |= GENL_CMD_CAP_DUMP;
+			if (ops->doit)
+				flags |= GENL_CMD_CAP_DO;
+			if (ops->policy)
+				flags |= GENL_CMD_CAP_HASPOL;
 
 			nest = nla_nest_start(skb, i + 1);
 			if (nest == NULL)
 				goto nla_put_failure;
 
 			if (nla_put_u32(skb, CTRL_ATTR_OP_ID, ops->cmd) ||
-			    nla_put_u32(skb, CTRL_ATTR_OP_FLAGS, ops->flags))
+			    nla_put_u32(skb, CTRL_ATTR_OP_FLAGS, flags))
 				goto nla_put_failure;
 
 			nla_nest_end(skb, nest);
-- 
1.8.4.rc3

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [RFC 8/7] genetlink: make all genl_ops users const
  2013-11-14  9:14 [RFC 0/7] genetlink: reduce ops size and complexity Johannes Berg
                   ` (6 preceding siblings ...)
  2013-11-14  9:14 ` [RFC 7/7] genetlink: allow making ops const Johannes Berg
@ 2013-11-14 13:41 ` Johannes Berg
  2013-11-14 14:01 ` [RFC 9/7] genetlink: make genl_ops flags a u8 and move to end Johannes Berg
                   ` (3 subsequent siblings)
  11 siblings, 0 replies; 29+ messages in thread
From: Johannes Berg @ 2013-11-14 13:41 UTC (permalink / raw)
  To: netdev

From: Johannes Berg <johannes.berg@intel.com>

Now that genl_ops are no longer modified in place when
registering, they can be made const. This patch was done
mostly with spatch:

@@
identifier ops;
@@
+const
 struct genl_ops ops[] = {
 ...
 };

(except the struct thing in net/openvswitch/datapath.c)

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 drivers/net/team/team.c               |  2 +-
 drivers/net/wireless/mac80211_hwsim.c |  2 +-
 kernel/taskstats.c                    |  2 +-
 net/core/drop_monitor.c               |  2 +-
 net/hsr/hsr_netlink.c                 |  2 +-
 net/ieee802154/netlink.c              |  2 +-
 net/ipv4/tcp_metrics.c                |  2 +-
 net/irda/irnetlink.c                  |  2 +-
 net/l2tp/l2tp_netlink.c               |  2 +-
 net/netfilter/ipvs/ip_vs_ctl.c        |  2 +-
 net/netlabel/netlabel_cipso_v4.c      |  2 +-
 net/netlabel/netlabel_mgmt.c          |  2 +-
 net/netlabel/netlabel_unlabeled.c     |  2 +-
 net/nfc/netlink.c                     |  2 +-
 net/openvswitch/datapath.c            | 10 +++++-----
 net/wimax/stack.c                     |  2 +-
 net/wireless/nl80211.c                |  2 +-
 17 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index 50e43e6..6390254 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -2644,7 +2644,7 @@ static int team_nl_cmd_port_list_get(struct sk_buff *skb,
 	return err;
 }
 
-static struct genl_ops team_nl_ops[] = {
+static const struct genl_ops team_nl_ops[] = {
 	{
 		.cmd = TEAM_CMD_NOOP,
 		.doit = team_nl_cmd_noop,
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index de0df86..cfc3fda 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -2097,7 +2097,7 @@ out:
 }
 
 /* Generic Netlink operations array */
-static struct genl_ops hwsim_ops[] = {
+static const struct genl_ops hwsim_ops[] = {
 	{
 		.cmd = HWSIM_CMD_REGISTER,
 		.policy = hwsim_genl_policy,
diff --git a/kernel/taskstats.c b/kernel/taskstats.c
index 609e77f..76595cd 100644
--- a/kernel/taskstats.c
+++ b/kernel/taskstats.c
@@ -673,7 +673,7 @@ err:
 	nlmsg_free(rep_skb);
 }
 
-static struct genl_ops taskstats_ops[] = {
+static const struct genl_ops taskstats_ops[] = {
 	{
 		.cmd		= TASKSTATS_CMD_GET,
 		.doit		= taskstats_user_cmd,
diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c
index 5e78d44..f9fe2f2 100644
--- a/net/core/drop_monitor.c
+++ b/net/core/drop_monitor.c
@@ -333,7 +333,7 @@ out:
 	return NOTIFY_DONE;
 }
 
-static struct genl_ops dropmon_ops[] = {
+static const struct genl_ops dropmon_ops[] = {
 	{
 		.cmd = NET_DM_CMD_CONFIG,
 		.doit = net_dm_cmd_config,
diff --git a/net/hsr/hsr_netlink.c b/net/hsr/hsr_netlink.c
index 8f52a9f..79d72ca 100644
--- a/net/hsr/hsr_netlink.c
+++ b/net/hsr/hsr_netlink.c
@@ -389,7 +389,7 @@ fail:
 }
 
 
-static struct genl_ops hsr_ops[] = {
+static const struct genl_ops hsr_ops[] = {
 	{
 		.cmd = HSR_C_GET_NODE_STATUS,
 		.flags = 0,
diff --git a/net/ieee802154/netlink.c b/net/ieee802154/netlink.c
index eb9faef..3ffcdbb 100644
--- a/net/ieee802154/netlink.c
+++ b/net/ieee802154/netlink.c
@@ -109,7 +109,7 @@ out:
 	return -ENOBUFS;
 }
 
-static struct genl_ops ieee8021154_ops[] = {
+static const struct genl_ops ieee8021154_ops[] = {
 	/* see nl-phy.c */
 	IEEE802154_DUMP(IEEE802154_LIST_PHY, ieee802154_list_phy,
 			ieee802154_dump_phy),
diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c
index 2ab09cb..9b780c1 100644
--- a/net/ipv4/tcp_metrics.c
+++ b/net/ipv4/tcp_metrics.c
@@ -988,7 +988,7 @@ static int tcp_metrics_nl_cmd_del(struct sk_buff *skb, struct genl_info *info)
 	return 0;
 }
 
-static struct genl_ops tcp_metrics_nl_ops[] = {
+static const struct genl_ops tcp_metrics_nl_ops[] = {
 	{
 		.cmd = TCP_METRICS_CMD_GET,
 		.doit = tcp_metrics_nl_cmd_get,
diff --git a/net/irda/irnetlink.c b/net/irda/irnetlink.c
index c3297126..bf5d7d4 100644
--- a/net/irda/irnetlink.c
+++ b/net/irda/irnetlink.c
@@ -131,7 +131,7 @@ static const struct nla_policy irda_nl_policy[IRDA_NL_ATTR_MAX + 1] = {
 	[IRDA_NL_ATTR_MODE] = { .type = NLA_U32 },
 };
 
-static struct genl_ops irda_nl_ops[] = {
+static const struct genl_ops irda_nl_ops[] = {
 	{
 		.cmd = IRDA_NL_CMD_SET_MODE,
 		.doit = irda_nl_set_mode,
diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c
index be446d5..57db66e 100644
--- a/net/l2tp/l2tp_netlink.c
+++ b/net/l2tp/l2tp_netlink.c
@@ -793,7 +793,7 @@ static struct nla_policy l2tp_nl_policy[L2TP_ATTR_MAX + 1] = {
 	},
 };
 
-static struct genl_ops l2tp_nl_ops[] = {
+static const struct genl_ops l2tp_nl_ops[] = {
 	{
 		.cmd = L2TP_CMD_NOOP,
 		.doit = l2tp_nl_cmd_noop,
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index 62786a4..fc8a04e 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -3567,7 +3567,7 @@ out:
 }
 
 
-static struct genl_ops ip_vs_genl_ops[] __read_mostly = {
+static const struct genl_ops ip_vs_genl_ops[] __read_mostly = {
 	{
 		.cmd	= IPVS_CMD_NEW_SERVICE,
 		.flags	= GENL_ADMIN_PERM,
diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c
index a110064..7066917 100644
--- a/net/netlabel/netlabel_cipso_v4.c
+++ b/net/netlabel/netlabel_cipso_v4.c
@@ -737,7 +737,7 @@ static int netlbl_cipsov4_remove(struct sk_buff *skb, struct genl_info *info)
  * NetLabel Generic NETLINK Command Definitions
  */
 
-static struct genl_ops netlbl_cipsov4_ops[] = {
+static const struct genl_ops netlbl_cipsov4_ops[] = {
 	{
 	.cmd = NLBL_CIPSOV4_C_ADD,
 	.flags = GENL_ADMIN_PERM,
diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c
index dd1c37d..7de6f66 100644
--- a/net/netlabel/netlabel_mgmt.c
+++ b/net/netlabel/netlabel_mgmt.c
@@ -705,7 +705,7 @@ version_failure:
  * NetLabel Generic NETLINK Command Definitions
  */
 
-static struct genl_ops netlbl_mgmt_genl_ops[] = {
+static const struct genl_ops netlbl_mgmt_genl_ops[] = {
 	{
 	.cmd = NLBL_MGMT_C_ADD,
 	.flags = GENL_ADMIN_PERM,
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c
index 8f08974..76ee925 100644
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -1323,7 +1323,7 @@ unlabel_staticlistdef_return:
  * NetLabel Generic NETLINK Command Definitions
  */
 
-static struct genl_ops netlbl_unlabel_genl_ops[] = {
+static const struct genl_ops netlbl_unlabel_genl_ops[] = {
 	{
 	.cmd = NLBL_UNLABEL_C_STATICADD,
 	.flags = GENL_ADMIN_PERM,
diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c
index 84b7e3e..f558561 100644
--- a/net/nfc/netlink.c
+++ b/net/nfc/netlink.c
@@ -1364,7 +1364,7 @@ static int nfc_genl_se_io(struct sk_buff *skb, struct genl_info *info)
 	return dev->ops->se_io(dev, se_idx, apdu, apdu_len, se_io_cb, ctx);
 }
 
-static struct genl_ops nfc_genl_ops[] = {
+static const struct genl_ops nfc_genl_ops[] = {
 	{
 		.cmd = NFC_CMD_GET_DEVICE,
 		.doit = nfc_genl_get_device,
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index 1408adc..91e1c92 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -557,7 +557,7 @@ static const struct nla_policy packet_policy[OVS_PACKET_ATTR_MAX + 1] = {
 	[OVS_PACKET_ATTR_ACTIONS] = { .type = NLA_NESTED },
 };
 
-static struct genl_ops dp_packet_genl_ops[] = {
+static const struct genl_ops dp_packet_genl_ops[] = {
 	{ .cmd = OVS_PACKET_CMD_EXECUTE,
 	  .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
 	  .policy = packet_policy,
@@ -1034,7 +1034,7 @@ static int ovs_flow_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb)
 	return skb->len;
 }
 
-static struct genl_ops dp_flow_genl_ops[] = {
+static const struct genl_ops dp_flow_genl_ops[] = {
 	{ .cmd = OVS_FLOW_CMD_NEW,
 	  .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
 	  .policy = flow_policy,
@@ -1392,7 +1392,7 @@ static int ovs_dp_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb)
 	return skb->len;
 }
 
-static struct genl_ops dp_datapath_genl_ops[] = {
+static const struct genl_ops dp_datapath_genl_ops[] = {
 	{ .cmd = OVS_DP_CMD_NEW,
 	  .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
 	  .policy = datapath_policy,
@@ -1753,7 +1753,7 @@ out:
 	return skb->len;
 }
 
-static struct genl_ops dp_vport_genl_ops[] = {
+static const struct genl_ops dp_vport_genl_ops[] = {
 	{ .cmd = OVS_VPORT_CMD_NEW,
 	  .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
 	  .policy = vport_policy,
@@ -1779,7 +1779,7 @@ static struct genl_ops dp_vport_genl_ops[] = {
 
 struct genl_family_and_ops {
 	struct genl_family *family;
-	struct genl_ops *ops;
+	const struct genl_ops *ops;
 	int n_ops;
 	struct genl_multicast_group *group;
 };
diff --git a/net/wimax/stack.c b/net/wimax/stack.c
index 4b7f15a..47170c9 100644
--- a/net/wimax/stack.c
+++ b/net/wimax/stack.c
@@ -415,7 +415,7 @@ static const struct nla_policy wimax_gnl_policy[WIMAX_GNL_ATTR_MAX + 1] = {
 	},
 };
 
-static struct genl_ops wimax_gnl_ops[] = {
+static const struct genl_ops wimax_gnl_ops[] = {
 	{
 		.cmd = WIMAX_GNL_OP_MSG_FROM_USER,
 		.flags = GENL_ADMIN_PERM,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index a7f4e79..7a92c45 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -8937,7 +8937,7 @@ static void nl80211_post_doit(struct genl_ops *ops, struct sk_buff *skb,
 		rtnl_unlock();
 }
 
-static struct genl_ops nl80211_ops[] = {
+static const struct genl_ops nl80211_ops[] = {
 	{
 		.cmd = NL80211_CMD_GET_WIPHY,
 		.doit = nl80211_get_wiphy,
-- 
1.8.4.rc3

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [RFC 9/7] genetlink: make genl_ops flags a u8 and move to end
  2013-11-14  9:14 [RFC 0/7] genetlink: reduce ops size and complexity Johannes Berg
                   ` (7 preceding siblings ...)
  2013-11-14 13:41 ` [RFC 8/7] genetlink: make all genl_ops users const Johannes Berg
@ 2013-11-14 14:01 ` Johannes Berg
  2013-11-14 14:36 ` [RFC 0/7] genetlink: reduce ops size and complexity Johannes Berg
                   ` (2 subsequent siblings)
  11 siblings, 0 replies; 29+ messages in thread
From: Johannes Berg @ 2013-11-14 14:01 UTC (permalink / raw)
  To: netdev

From: Johannes Berg <johannes.berg@intel.com>

To save some space in the struct on 32-bit systems,
make the flags a u8 (only 4 bits are used) and also
move them to the end of the struct.

This has no impact on 64-bit systems as alignment of
the struct in an array uses up the space anyway.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 include/net/genetlink.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/include/net/genetlink.h b/include/net/genetlink.h
index 0b6b10b..eddcdf2 100644
--- a/include/net/genetlink.h
+++ b/include/net/genetlink.h
@@ -110,15 +110,15 @@ static inline void genl_info_net_set(struct genl_info *info, struct net *net)
  * @ops_list: operations list
  */
 struct genl_ops {
-	u8			cmd;
-	u8			internal_flags;
-	unsigned int		flags;
 	const struct nla_policy	*policy;
 	int		       (*doit)(struct sk_buff *skb,
 				       struct genl_info *info);
 	int		       (*dumpit)(struct sk_buff *skb,
 					 struct netlink_callback *cb);
 	int		       (*done)(struct netlink_callback *cb);
+	u8			cmd;
+	u8			internal_flags;
+	u8			flags;
 };
 
 int __genl_register_family(struct genl_family *family);
-- 
1.8.4.rc3

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* Re: [RFC 0/7] genetlink: reduce ops size and complexity
  2013-11-14  9:14 [RFC 0/7] genetlink: reduce ops size and complexity Johannes Berg
                   ` (8 preceding siblings ...)
  2013-11-14 14:01 ` [RFC 9/7] genetlink: make genl_ops flags a u8 and move to end Johannes Berg
@ 2013-11-14 14:36 ` Johannes Berg
  2013-11-14 16:02 ` Johannes Berg
  2013-11-14 16:14 ` [PATCH 0/9] genetlink: reduce ops size and complexity (v2) Johannes Berg
  11 siblings, 0 replies; 29+ messages in thread
From: Johannes Berg @ 2013-11-14 14:36 UTC (permalink / raw)
  To: netdev

On Thu, 2013-11-14 at 10:14 +0100, Johannes Berg wrote:
> This series of patches updates a few genetlink users and then
> makes the ops a static const array, reducing kernel size and
> code complexity.

FWIW, for the full series (including patches 8 and 9) we get

 drivers/net/team/team.c               |    2 
 drivers/net/wireless/mac80211_hwsim.c |    2 
 include/net/genetlink.h               |   17 +---
 kernel/taskstats.c                    |   39 +++------
 net/core/drop_monitor.c               |    2 
 net/hsr/hsr_netlink.c                 |   46 ++++-------
 net/ieee802154/ieee802154.h           |   19 ++++
 net/ieee802154/netlink.c              |   28 +++++--
 net/ieee802154/nl-mac.c               |   61 ++-------------
 net/ieee802154/nl-phy.c               |   37 +--------
 net/ipv4/tcp_metrics.c                |    2 
 net/irda/irnetlink.c                  |    2 
 net/l2tp/l2tp_netlink.c               |    2 
 net/netfilter/ipvs/ip_vs_ctl.c        |    2 
 net/netlabel/netlabel_cipso_v4.c      |    2 
 net/netlabel/netlabel_mgmt.c          |    2 
 net/netlabel/netlabel_unlabeled.c     |    2 
 net/netlink/genetlink.c               |  133
+++++++++-------------------------
 net/nfc/netlink.c                     |    2 
 net/openvswitch/datapath.c            |   10 +-
 net/wimax/op-msg.c                    |   25 ------
 net/wimax/op-reset.c                  |   17 ----
 net/wimax/op-rfkill.c                 |   21 -----
 net/wimax/op-state-get.c              |   17 ----
 net/wimax/stack.c                     |   79 ++++++++++----------
 net/wimax/wimax-internal.h            |    7 +
 net/wireless/nl80211.c                |    2 
 27 files changed, 190 insertions(+), 390 deletions(-)

johannes

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [RFC 0/7] genetlink: reduce ops size and complexity
  2013-11-14  9:14 [RFC 0/7] genetlink: reduce ops size and complexity Johannes Berg
                   ` (9 preceding siblings ...)
  2013-11-14 14:36 ` [RFC 0/7] genetlink: reduce ops size and complexity Johannes Berg
@ 2013-11-14 16:02 ` Johannes Berg
  2013-11-14 16:14 ` [PATCH 0/9] genetlink: reduce ops size and complexity (v2) Johannes Berg
  11 siblings, 0 replies; 29+ messages in thread
From: Johannes Berg @ 2013-11-14 16:02 UTC (permalink / raw)
  To: netdev

On Thu, 2013-11-14 at 10:14 +0100, Johannes Berg wrote:
> This series of patches updates a few genetlink users and then
> makes the ops a static const array, reducing kernel size and
> code complexity.
> 
> Comments welcome.

Well, there were some major bugs in here, but now it seems to work. I'll
repost properly with everybody in CC.

johannes

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 0/9] genetlink: reduce ops size and complexity (v2)
  2013-11-14  9:14 [RFC 0/7] genetlink: reduce ops size and complexity Johannes Berg
                   ` (10 preceding siblings ...)
  2013-11-14 16:02 ` Johannes Berg
@ 2013-11-14 16:14 ` Johannes Berg
  2013-11-14 16:14   ` [PATCH 1/9] taskstats: use genl_register_family_with_ops() Johannes Berg
                     ` (9 more replies)
  11 siblings, 10 replies; 29+ messages in thread
From: Johannes Berg @ 2013-11-14 16:14 UTC (permalink / raw)
  To: netdev
  Cc: linux-wimax, Balbir Singh, netfilter-devel, Alexander Smirnov,
	Dmitry Eremin-Solenikov

As before - reduce the complexity and data/code size of genetlink ops
by making them an array rather than a linked list. Most users already
use an array thanks to genl_register_family_with_ops(), so convert the
remaining ones allowing us to get rid of the list head in each op.

Also make them const, this just makes sense at that point and the security
people like making function pointers const as well :-)

johannes

^ permalink raw reply	[flat|nested] 29+ messages in thread

* [PATCH 1/9] taskstats: use genl_register_family_with_ops()
  2013-11-14 16:14 ` [PATCH 0/9] genetlink: reduce ops size and complexity (v2) Johannes Berg
@ 2013-11-14 16:14   ` Johannes Berg
  2013-11-14 16:14   ` [PATCH 2/9] hsr: " Johannes Berg
                     ` (8 subsequent siblings)
  9 siblings, 0 replies; 29+ messages in thread
From: Johannes Berg @ 2013-11-14 16:14 UTC (permalink / raw)
  To: netdev
  Cc: linux-wimax, Balbir Singh, netfilter-devel, Alexander Smirnov,
	Dmitry Eremin-Solenikov, Johannes Berg

From: Johannes Berg <johannes.berg@intel.com>

This simplifies the code since there's no longer a
need to have error handling in the registration.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 kernel/taskstats.c | 39 ++++++++++++++-------------------------
 1 file changed, 14 insertions(+), 25 deletions(-)

diff --git a/kernel/taskstats.c b/kernel/taskstats.c
index 9f4618e..609e77f 100644
--- a/kernel/taskstats.c
+++ b/kernel/taskstats.c
@@ -673,17 +673,18 @@ err:
 	nlmsg_free(rep_skb);
 }
 
-static struct genl_ops taskstats_ops = {
-	.cmd		= TASKSTATS_CMD_GET,
-	.doit		= taskstats_user_cmd,
-	.policy		= taskstats_cmd_get_policy,
-	.flags		= GENL_ADMIN_PERM,
-};
-
-static struct genl_ops cgroupstats_ops = {
-	.cmd		= CGROUPSTATS_CMD_GET,
-	.doit		= cgroupstats_user_cmd,
-	.policy		= cgroupstats_cmd_get_policy,
+static struct genl_ops taskstats_ops[] = {
+	{
+		.cmd		= TASKSTATS_CMD_GET,
+		.doit		= taskstats_user_cmd,
+		.policy		= taskstats_cmd_get_policy,
+		.flags		= GENL_ADMIN_PERM,
+	},
+	{
+		.cmd		= CGROUPSTATS_CMD_GET,
+		.doit		= cgroupstats_user_cmd,
+		.policy		= cgroupstats_cmd_get_policy,
+	},
 };
 
 /* Needed early in initialization */
@@ -702,26 +703,14 @@ static int __init taskstats_init(void)
 {
 	int rc;
 
-	rc = genl_register_family(&family);
+	rc = genl_register_family_with_ops(&family, taskstats_ops,
+					   ARRAY_SIZE(taskstats_ops));
 	if (rc)
 		return rc;
 
-	rc = genl_register_ops(&family, &taskstats_ops);
-	if (rc < 0)
-		goto err;
-
-	rc = genl_register_ops(&family, &cgroupstats_ops);
-	if (rc < 0)
-		goto err_cgroup_ops;
-
 	family_registered = 1;
 	pr_info("registered taskstats version %d\n", TASKSTATS_GENL_VERSION);
 	return 0;
-err_cgroup_ops:
-	genl_unregister_ops(&family, &taskstats_ops);
-err:
-	genl_unregister_family(&family);
-	return rc;
 }
 
 /*
-- 
1.8.4.rc3


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 2/9] hsr: use genl_register_family_with_ops()
  2013-11-14 16:14 ` [PATCH 0/9] genetlink: reduce ops size and complexity (v2) Johannes Berg
  2013-11-14 16:14   ` [PATCH 1/9] taskstats: use genl_register_family_with_ops() Johannes Berg
@ 2013-11-14 16:14   ` Johannes Berg
  2013-11-14 16:14   ` [PATCH 3/9] ieee802154: " Johannes Berg
                     ` (7 subsequent siblings)
  9 siblings, 0 replies; 29+ messages in thread
From: Johannes Berg @ 2013-11-14 16:14 UTC (permalink / raw)
  To: netdev
  Cc: linux-wimax, Balbir Singh, netfilter-devel, Alexander Smirnov,
	Dmitry Eremin-Solenikov, Johannes Berg

From: Johannes Berg <johannes.berg@intel.com>

This simplifies the code since there's no longer a
need to have error handling in the registration.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 net/hsr/hsr_netlink.c | 46 +++++++++++++++++-----------------------------
 1 file changed, 17 insertions(+), 29 deletions(-)

diff --git a/net/hsr/hsr_netlink.c b/net/hsr/hsr_netlink.c
index 4e66bf6..8f52a9f 100644
--- a/net/hsr/hsr_netlink.c
+++ b/net/hsr/hsr_netlink.c
@@ -306,15 +306,6 @@ fail:
 	return res;
 }
 
-static struct genl_ops hsr_ops_get_node_status = {
-	.cmd = HSR_C_GET_NODE_STATUS,
-	.flags = 0,
-	.policy = hsr_genl_policy,
-	.doit = hsr_get_node_status,
-	.dumpit = NULL,
-};
-
-
 /* Get a list of MacAddressA of all nodes known to this node (other than self).
  */
 static int hsr_get_node_list(struct sk_buff *skb_in, struct genl_info *info)
@@ -398,12 +389,21 @@ fail:
 }
 
 
-static struct genl_ops hsr_ops_get_node_list = {
-	.cmd = HSR_C_GET_NODE_LIST,
-	.flags = 0,
-	.policy = hsr_genl_policy,
-	.doit = hsr_get_node_list,
-	.dumpit = NULL,
+static struct genl_ops hsr_ops[] = {
+	{
+		.cmd = HSR_C_GET_NODE_STATUS,
+		.flags = 0,
+		.policy = hsr_genl_policy,
+		.doit = hsr_get_node_status,
+		.dumpit = NULL,
+	},
+	{
+		.cmd = HSR_C_GET_NODE_LIST,
+		.flags = 0,
+		.policy = hsr_genl_policy,
+		.doit = hsr_get_node_list,
+		.dumpit = NULL,
+	},
 };
 
 int __init hsr_netlink_init(void)
@@ -414,18 +414,11 @@ int __init hsr_netlink_init(void)
 	if (rc)
 		goto fail_rtnl_link_register;
 
-	rc = genl_register_family(&hsr_genl_family);
+	rc = genl_register_family_with_ops(&hsr_genl_family, hsr_ops,
+					   ARRAY_SIZE(hsr_ops));
 	if (rc)
 		goto fail_genl_register_family;
 
-	rc = genl_register_ops(&hsr_genl_family, &hsr_ops_get_node_status);
-	if (rc)
-		goto fail_genl_register_ops;
-
-	rc = genl_register_ops(&hsr_genl_family, &hsr_ops_get_node_list);
-	if (rc)
-		goto fail_genl_register_ops_node_list;
-
 	rc = genl_register_mc_group(&hsr_genl_family, &hsr_network_genl_mcgrp);
 	if (rc)
 		goto fail_genl_register_mc_group;
@@ -433,10 +426,6 @@ int __init hsr_netlink_init(void)
 	return 0;
 
 fail_genl_register_mc_group:
-	genl_unregister_ops(&hsr_genl_family, &hsr_ops_get_node_list);
-fail_genl_register_ops_node_list:
-	genl_unregister_ops(&hsr_genl_family, &hsr_ops_get_node_status);
-fail_genl_register_ops:
 	genl_unregister_family(&hsr_genl_family);
 fail_genl_register_family:
 	rtnl_link_unregister(&hsr_link_ops);
@@ -448,7 +437,6 @@ fail_rtnl_link_register:
 void __exit hsr_netlink_exit(void)
 {
 	genl_unregister_mc_group(&hsr_genl_family, &hsr_network_genl_mcgrp);
-	genl_unregister_ops(&hsr_genl_family, &hsr_ops_get_node_status);
 	genl_unregister_family(&hsr_genl_family);
 
 	rtnl_link_unregister(&hsr_link_ops);
-- 
1.8.4.rc3


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 3/9] ieee802154: use genl_register_family_with_ops()
  2013-11-14 16:14 ` [PATCH 0/9] genetlink: reduce ops size and complexity (v2) Johannes Berg
  2013-11-14 16:14   ` [PATCH 1/9] taskstats: use genl_register_family_with_ops() Johannes Berg
  2013-11-14 16:14   ` [PATCH 2/9] hsr: " Johannes Berg
@ 2013-11-14 16:14   ` Johannes Berg
  2013-11-14 16:14   ` [PATCH 4/9] wimax: " Johannes Berg
                     ` (6 subsequent siblings)
  9 siblings, 0 replies; 29+ messages in thread
From: Johannes Berg @ 2013-11-14 16:14 UTC (permalink / raw)
  To: netdev
  Cc: linux-wimax, Balbir Singh, netfilter-devel, Alexander Smirnov,
	Dmitry Eremin-Solenikov, Johannes Berg

From: Johannes Berg <johannes.berg@intel.com>

This simplifies the code since there's no longer a need to
have error handling in the registration.

Unfortunately it means more extern function declarations are
needed, but the overall goal would seem to justify this.

While at it, also fix the registration error path - if the
family registration failed then it shouldn't be unregistered.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 net/ieee802154/ieee802154.h | 19 ++++++++++++--
 net/ieee802154/netlink.c    | 28 +++++++++++++++------
 net/ieee802154/nl-mac.c     | 61 +++++++--------------------------------------
 net/ieee802154/nl-phy.c     | 37 +++------------------------
 4 files changed, 51 insertions(+), 94 deletions(-)

diff --git a/net/ieee802154/ieee802154.h b/net/ieee802154/ieee802154.h
index aadec42..14d5dab 100644
--- a/net/ieee802154/ieee802154.h
+++ b/net/ieee802154/ieee802154.h
@@ -47,7 +47,22 @@ struct sk_buff *ieee802154_nl_new_reply(struct genl_info *info,
 int ieee802154_nl_reply(struct sk_buff *msg, struct genl_info *info);
 
 extern struct genl_family nl802154_family;
-int nl802154_mac_register(void);
-int nl802154_phy_register(void);
+
+/* genetlink ops/groups */
+int ieee802154_list_phy(struct sk_buff *skb, struct genl_info *info);
+int ieee802154_dump_phy(struct sk_buff *skb, struct netlink_callback *cb);
+int ieee802154_add_iface(struct sk_buff *skb, struct genl_info *info);
+int ieee802154_del_iface(struct sk_buff *skb, struct genl_info *info);
+
+extern struct genl_multicast_group ieee802154_coord_mcgrp;
+extern struct genl_multicast_group ieee802154_beacon_mcgrp;
+
+int ieee802154_associate_req(struct sk_buff *skb, struct genl_info *info);
+int ieee802154_associate_resp(struct sk_buff *skb, struct genl_info *info);
+int ieee802154_disassociate_req(struct sk_buff *skb, struct genl_info *info);
+int ieee802154_scan_req(struct sk_buff *skb, struct genl_info *info);
+int ieee802154_start_req(struct sk_buff *skb, struct genl_info *info);
+int ieee802154_list_iface(struct sk_buff *skb, struct genl_info *info);
+int ieee802154_dump_iface(struct sk_buff *skb, struct netlink_callback *cb);
 
 #endif
diff --git a/net/ieee802154/netlink.c b/net/ieee802154/netlink.c
index 7e49bbc..eb9faef 100644
--- a/net/ieee802154/netlink.c
+++ b/net/ieee802154/netlink.c
@@ -109,24 +109,39 @@ out:
 	return -ENOBUFS;
 }
 
+static struct genl_ops ieee8021154_ops[] = {
+	/* see nl-phy.c */
+	IEEE802154_DUMP(IEEE802154_LIST_PHY, ieee802154_list_phy,
+			ieee802154_dump_phy),
+	IEEE802154_OP(IEEE802154_ADD_IFACE, ieee802154_add_iface),
+	IEEE802154_OP(IEEE802154_DEL_IFACE, ieee802154_del_iface),
+	/* see nl-mac.c */
+	IEEE802154_OP(IEEE802154_ASSOCIATE_REQ, ieee802154_associate_req),
+	IEEE802154_OP(IEEE802154_ASSOCIATE_RESP, ieee802154_associate_resp),
+	IEEE802154_OP(IEEE802154_DISASSOCIATE_REQ, ieee802154_disassociate_req),
+	IEEE802154_OP(IEEE802154_SCAN_REQ, ieee802154_scan_req),
+	IEEE802154_OP(IEEE802154_START_REQ, ieee802154_start_req),
+	IEEE802154_DUMP(IEEE802154_LIST_IFACE, ieee802154_list_iface,
+			ieee802154_dump_iface),
+};
+
 int __init ieee802154_nl_init(void)
 {
 	int rc;
 
-	rc = genl_register_family(&nl802154_family);
+	rc = genl_register_family_with_ops(&nl802154_family, ieee8021154_ops,
+					   ARRAY_SIZE(ieee8021154_ops));
 	if (rc)
-		goto fail;
+		return rc;
 
-	rc = nl802154_mac_register();
+	rc = genl_register_mc_group(&nl802154_family, &ieee802154_coord_mcgrp);
 	if (rc)
 		goto fail;
 
-	rc = nl802154_phy_register();
+	rc = genl_register_mc_group(&nl802154_family, &ieee802154_beacon_mcgrp);
 	if (rc)
 		goto fail;
-
 	return 0;
-
 fail:
 	genl_unregister_family(&nl802154_family);
 	return rc;
@@ -136,4 +151,3 @@ void __exit ieee802154_nl_exit(void)
 {
 	genl_unregister_family(&nl802154_family);
 }
-
diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c
index b0bdd8c..28d4930 100644
--- a/net/ieee802154/nl-mac.c
+++ b/net/ieee802154/nl-mac.c
@@ -39,11 +39,11 @@
 
 #include "ieee802154.h"
 
-static struct genl_multicast_group ieee802154_coord_mcgrp = {
+struct genl_multicast_group ieee802154_coord_mcgrp = {
 	.name		= IEEE802154_MCAST_COORD_NAME,
 };
 
-static struct genl_multicast_group ieee802154_beacon_mcgrp = {
+struct genl_multicast_group ieee802154_beacon_mcgrp = {
 	.name		= IEEE802154_MCAST_BEACON_NAME,
 };
 
@@ -309,8 +309,7 @@ static struct net_device *ieee802154_nl_get_dev(struct genl_info *info)
 	return dev;
 }
 
-static int ieee802154_associate_req(struct sk_buff *skb,
-		struct genl_info *info)
+int ieee802154_associate_req(struct sk_buff *skb, struct genl_info *info)
 {
 	struct net_device *dev;
 	struct ieee802154_addr addr;
@@ -357,8 +356,7 @@ out:
 	return ret;
 }
 
-static int ieee802154_associate_resp(struct sk_buff *skb,
-		struct genl_info *info)
+int ieee802154_associate_resp(struct sk_buff *skb, struct genl_info *info)
 {
 	struct net_device *dev;
 	struct ieee802154_addr addr;
@@ -390,8 +388,7 @@ out:
 	return ret;
 }
 
-static int ieee802154_disassociate_req(struct sk_buff *skb,
-		struct genl_info *info)
+int ieee802154_disassociate_req(struct sk_buff *skb, struct genl_info *info)
 {
 	struct net_device *dev;
 	struct ieee802154_addr addr;
@@ -433,7 +430,7 @@ out:
  * PAN_coordinator, battery_life_extension = 0,
  * coord_realignment = 0, security_enable = 0
 */
-static int ieee802154_start_req(struct sk_buff *skb, struct genl_info *info)
+int ieee802154_start_req(struct sk_buff *skb, struct genl_info *info)
 {
 	struct net_device *dev;
 	struct ieee802154_addr addr;
@@ -492,7 +489,7 @@ out:
 	return ret;
 }
 
-static int ieee802154_scan_req(struct sk_buff *skb, struct genl_info *info)
+int ieee802154_scan_req(struct sk_buff *skb, struct genl_info *info)
 {
 	struct net_device *dev;
 	int ret = -EOPNOTSUPP;
@@ -530,8 +527,7 @@ out:
 	return ret;
 }
 
-static int ieee802154_list_iface(struct sk_buff *skb,
-	struct genl_info *info)
+int ieee802154_list_iface(struct sk_buff *skb, struct genl_info *info)
 {
 	/* Request for interface name, index, type, IEEE address,
 	   PAN Id, short address */
@@ -565,8 +561,7 @@ out_dev:
 
 }
 
-static int ieee802154_dump_iface(struct sk_buff *skb,
-	struct netlink_callback *cb)
+int ieee802154_dump_iface(struct sk_buff *skb, struct netlink_callback *cb)
 {
 	struct net *net = sock_net(skb->sk);
 	struct net_device *dev;
@@ -590,41 +585,3 @@ cont:
 
 	return skb->len;
 }
-
-static struct genl_ops ieee802154_coordinator_ops[] = {
-	IEEE802154_OP(IEEE802154_ASSOCIATE_REQ, ieee802154_associate_req),
-	IEEE802154_OP(IEEE802154_ASSOCIATE_RESP, ieee802154_associate_resp),
-	IEEE802154_OP(IEEE802154_DISASSOCIATE_REQ, ieee802154_disassociate_req),
-	IEEE802154_OP(IEEE802154_SCAN_REQ, ieee802154_scan_req),
-	IEEE802154_OP(IEEE802154_START_REQ, ieee802154_start_req),
-	IEEE802154_DUMP(IEEE802154_LIST_IFACE, ieee802154_list_iface,
-							ieee802154_dump_iface),
-};
-
-/*
- * No need to unregister as family unregistration will do it.
- */
-int nl802154_mac_register(void)
-{
-	int i;
-	int rc;
-
-	rc = genl_register_mc_group(&nl802154_family,
-			&ieee802154_coord_mcgrp);
-	if (rc)
-		return rc;
-
-	rc = genl_register_mc_group(&nl802154_family,
-			&ieee802154_beacon_mcgrp);
-	if (rc)
-		return rc;
-
-	for (i = 0; i < ARRAY_SIZE(ieee802154_coordinator_ops); i++) {
-		rc = genl_register_ops(&nl802154_family,
-				&ieee802154_coordinator_ops[i]);
-		if (rc)
-			return rc;
-	}
-
-	return 0;
-}
diff --git a/net/ieee802154/nl-phy.c b/net/ieee802154/nl-phy.c
index 22b1a70..d08c7a4 100644
--- a/net/ieee802154/nl-phy.c
+++ b/net/ieee802154/nl-phy.c
@@ -77,8 +77,7 @@ out:
 	return -EMSGSIZE;
 }
 
-static int ieee802154_list_phy(struct sk_buff *skb,
-	struct genl_info *info)
+int ieee802154_list_phy(struct sk_buff *skb, struct genl_info *info)
 {
 	/* Request for interface name, index, type, IEEE address,
 	   PAN Id, short address */
@@ -151,8 +150,7 @@ static int ieee802154_dump_phy_iter(struct wpan_phy *phy, void *_data)
 	return 0;
 }
 
-static int ieee802154_dump_phy(struct sk_buff *skb,
-	struct netlink_callback *cb)
+int ieee802154_dump_phy(struct sk_buff *skb, struct netlink_callback *cb)
 {
 	struct dump_phy_data data = {
 		.cb = cb,
@@ -170,8 +168,7 @@ static int ieee802154_dump_phy(struct sk_buff *skb,
 	return skb->len;
 }
 
-static int ieee802154_add_iface(struct sk_buff *skb,
-		struct genl_info *info)
+int ieee802154_add_iface(struct sk_buff *skb, struct genl_info *info)
 {
 	struct sk_buff *msg;
 	struct wpan_phy *phy;
@@ -273,8 +270,7 @@ out_dev:
 	return rc;
 }
 
-static int ieee802154_del_iface(struct sk_buff *skb,
-		struct genl_info *info)
+int ieee802154_del_iface(struct sk_buff *skb, struct genl_info *info)
 {
 	struct sk_buff *msg;
 	struct wpan_phy *phy;
@@ -356,28 +352,3 @@ out_dev:
 
 	return rc;
 }
-
-static struct genl_ops ieee802154_phy_ops[] = {
-	IEEE802154_DUMP(IEEE802154_LIST_PHY, ieee802154_list_phy,
-							ieee802154_dump_phy),
-	IEEE802154_OP(IEEE802154_ADD_IFACE, ieee802154_add_iface),
-	IEEE802154_OP(IEEE802154_DEL_IFACE, ieee802154_del_iface),
-};
-
-/*
- * No need to unregister as family unregistration will do it.
- */
-int nl802154_phy_register(void)
-{
-	int i;
-	int rc;
-
-	for (i = 0; i < ARRAY_SIZE(ieee802154_phy_ops); i++) {
-		rc = genl_register_ops(&nl802154_family,
-				&ieee802154_phy_ops[i]);
-		if (rc)
-			return rc;
-	}
-
-	return 0;
-}
-- 
1.8.4.rc3

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 4/9] wimax: use genl_register_family_with_ops()
  2013-11-14 16:14 ` [PATCH 0/9] genetlink: reduce ops size and complexity (v2) Johannes Berg
                     ` (2 preceding siblings ...)
  2013-11-14 16:14   ` [PATCH 3/9] ieee802154: " Johannes Berg
@ 2013-11-14 16:14   ` Johannes Berg
  2013-11-14 16:14   ` [PATCH 5/9] genetlink: remove genl_register_ops/genl_unregister_ops Johannes Berg
                     ` (5 subsequent siblings)
  9 siblings, 0 replies; 29+ messages in thread
From: Johannes Berg @ 2013-11-14 16:14 UTC (permalink / raw)
  To: netdev
  Cc: linux-wimax, Balbir Singh, netfilter-devel, Alexander Smirnov,
	Dmitry Eremin-Solenikov, Johannes Berg

From: Johannes Berg <johannes.berg@intel.com>

This simplifies the code since there's no longer a need to
have error handling in the registration.

Unfortunately it means more extern function declarations are
needed, but the overall goal would seem to justify this.

Due to the removal of duplication in the netlink policies,
this reduces the size of wimax by almost 1k.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 net/wimax/op-msg.c         | 25 ---------------
 net/wimax/op-reset.c       | 17 ----------
 net/wimax/op-rfkill.c      | 21 ------------
 net/wimax/op-state-get.c   | 17 ----------
 net/wimax/stack.c          | 79 +++++++++++++++++++++++-----------------------
 net/wimax/wimax-internal.h |  7 ++++
 6 files changed, 47 insertions(+), 119 deletions(-)

diff --git a/net/wimax/op-msg.c b/net/wimax/op-msg.c
index 0694d62..ff19cbe 100644
--- a/net/wimax/op-msg.c
+++ b/net/wimax/op-msg.c
@@ -321,17 +321,6 @@ int wimax_msg(struct wimax_dev *wimax_dev, const char *pipe_name,
 }
 EXPORT_SYMBOL_GPL(wimax_msg);
 
-
-static const struct nla_policy wimax_gnl_msg_policy[WIMAX_GNL_ATTR_MAX + 1] = {
-	[WIMAX_GNL_MSG_IFIDX] = {
-		.type = NLA_U32,
-	},
-	[WIMAX_GNL_MSG_DATA] = {
-		.type = NLA_UNSPEC,	/* libnl doesn't grok BINARY yet */
-	},
-};
-
-
 /*
  * Relays a message from user space to the driver
  *
@@ -340,7 +329,6 @@ static const struct nla_policy wimax_gnl_msg_policy[WIMAX_GNL_ATTR_MAX + 1] = {
  *
  * This call will block while handling/relaying the message.
  */
-static
 int wimax_gnl_doit_msg_from_user(struct sk_buff *skb, struct genl_info *info)
 {
 	int result, ifindex;
@@ -418,16 +406,3 @@ error_no_wimax_dev:
 	return result;
 }
 
-
-/*
- * Generic Netlink glue
- */
-
-struct genl_ops wimax_gnl_msg_from_user = {
-	.cmd = WIMAX_GNL_OP_MSG_FROM_USER,
-	.flags = GENL_ADMIN_PERM,
-	.policy = wimax_gnl_msg_policy,
-	.doit = wimax_gnl_doit_msg_from_user,
-	.dumpit = NULL,
-};
-
diff --git a/net/wimax/op-reset.c b/net/wimax/op-reset.c
index 7ceffe3..eb45807 100644
--- a/net/wimax/op-reset.c
+++ b/net/wimax/op-reset.c
@@ -92,13 +92,6 @@ int wimax_reset(struct wimax_dev *wimax_dev)
 EXPORT_SYMBOL(wimax_reset);
 
 
-static const struct nla_policy wimax_gnl_reset_policy[WIMAX_GNL_ATTR_MAX + 1] = {
-	[WIMAX_GNL_RESET_IFIDX] = {
-		.type = NLA_U32,
-	},
-};
-
-
 /*
  * Exporting to user space over generic netlink
  *
@@ -106,7 +99,6 @@ static const struct nla_policy wimax_gnl_reset_policy[WIMAX_GNL_ATTR_MAX + 1] =
  *
  * No attributes.
  */
-static
 int wimax_gnl_doit_reset(struct sk_buff *skb, struct genl_info *info)
 {
 	int result, ifindex;
@@ -130,12 +122,3 @@ error_no_wimax_dev:
 	d_fnend(3, NULL, "(skb %p info %p) = %d\n", skb, info, result);
 	return result;
 }
-
-
-struct genl_ops wimax_gnl_reset = {
-	.cmd = WIMAX_GNL_OP_RESET,
-	.flags = GENL_ADMIN_PERM,
-	.policy = wimax_gnl_reset_policy,
-	.doit = wimax_gnl_doit_reset,
-	.dumpit = NULL,
-};
diff --git a/net/wimax/op-rfkill.c b/net/wimax/op-rfkill.c
index 7ab60ba..403078d 100644
--- a/net/wimax/op-rfkill.c
+++ b/net/wimax/op-rfkill.c
@@ -411,17 +411,6 @@ void wimax_rfkill_rm(struct wimax_dev *wimax_dev)
  * just query).
  */
 
-static const struct nla_policy wimax_gnl_rfkill_policy[WIMAX_GNL_ATTR_MAX + 1] = {
-	[WIMAX_GNL_RFKILL_IFIDX] = {
-		.type = NLA_U32,
-	},
-	[WIMAX_GNL_RFKILL_STATE] = {
-		.type = NLA_U32		/* enum wimax_rf_state */
-	},
-};
-
-
-static
 int wimax_gnl_doit_rfkill(struct sk_buff *skb, struct genl_info *info)
 {
 	int result, ifindex;
@@ -457,13 +446,3 @@ error_no_wimax_dev:
 	d_fnend(3, NULL, "(skb %p info %p) = %d\n", skb, info, result);
 	return result;
 }
-
-
-struct genl_ops wimax_gnl_rfkill = {
-	.cmd = WIMAX_GNL_OP_RFKILL,
-	.flags = GENL_ADMIN_PERM,
-	.policy = wimax_gnl_rfkill_policy,
-	.doit = wimax_gnl_doit_rfkill,
-	.dumpit = NULL,
-};
-
diff --git a/net/wimax/op-state-get.c b/net/wimax/op-state-get.c
index aff8776..995c08c 100644
--- a/net/wimax/op-state-get.c
+++ b/net/wimax/op-state-get.c
@@ -33,13 +33,6 @@
 #include "debug-levels.h"
 
 
-static const struct nla_policy wimax_gnl_state_get_policy[WIMAX_GNL_ATTR_MAX + 1] = {
-	[WIMAX_GNL_STGET_IFIDX] = {
-		.type = NLA_U32,
-	},
-};
-
-
 /*
  * Exporting to user space over generic netlink
  *
@@ -48,7 +41,6 @@ static const struct nla_policy wimax_gnl_state_get_policy[WIMAX_GNL_ATTR_MAX + 1
  *
  * No attributes.
  */
-static
 int wimax_gnl_doit_state_get(struct sk_buff *skb, struct genl_info *info)
 {
 	int result, ifindex;
@@ -72,12 +64,3 @@ error_no_wimax_dev:
 	d_fnend(3, NULL, "(skb %p info %p) = %d\n", skb, info, result);
 	return result;
 }
-
-
-struct genl_ops wimax_gnl_state_get = {
-	.cmd = WIMAX_GNL_OP_STATE_GET,
-	.flags = GENL_ADMIN_PERM,
-	.policy = wimax_gnl_state_get_policy,
-	.doit = wimax_gnl_doit_state_get,
-	.dumpit = NULL,
-};
diff --git a/net/wimax/stack.c b/net/wimax/stack.c
index a6470ac..4b7f15a 100644
--- a/net/wimax/stack.c
+++ b/net/wimax/stack.c
@@ -402,22 +402,44 @@ void wimax_dev_init(struct wimax_dev *wimax_dev)
 }
 EXPORT_SYMBOL_GPL(wimax_dev_init);
 
-/*
- * This extern is declared here because it's easier to keep track --
- * both declarations are a list of the same
- */
-extern struct genl_ops
-	wimax_gnl_msg_from_user,
-	wimax_gnl_reset,
-	wimax_gnl_rfkill,
-	wimax_gnl_state_get;
+static const struct nla_policy wimax_gnl_policy[WIMAX_GNL_ATTR_MAX + 1] = {
+	[WIMAX_GNL_RESET_IFIDX] = { .type = NLA_U32, },
+	[WIMAX_GNL_RFKILL_IFIDX] = { .type = NLA_U32, },
+	[WIMAX_GNL_RFKILL_STATE] = {
+		.type = NLA_U32		/* enum wimax_rf_state */
+	},
+	[WIMAX_GNL_STGET_IFIDX] = { .type = NLA_U32, },
+	[WIMAX_GNL_MSG_IFIDX] = { .type = NLA_U32, },
+	[WIMAX_GNL_MSG_DATA] = {
+		.type = NLA_UNSPEC,	/* libnl doesn't grok BINARY yet */
+	},
+};
 
-static
-struct genl_ops *wimax_gnl_ops[] = {
-	&wimax_gnl_msg_from_user,
-	&wimax_gnl_reset,
-	&wimax_gnl_rfkill,
-	&wimax_gnl_state_get,
+static struct genl_ops wimax_gnl_ops[] = {
+	{
+		.cmd = WIMAX_GNL_OP_MSG_FROM_USER,
+		.flags = GENL_ADMIN_PERM,
+		.policy = wimax_gnl_policy,
+		.doit = wimax_gnl_doit_msg_from_user,
+	},
+	{
+		.cmd = WIMAX_GNL_OP_RESET,
+		.flags = GENL_ADMIN_PERM,
+		.policy = wimax_gnl_policy,
+		.doit = wimax_gnl_doit_reset,
+	},
+	{
+		.cmd = WIMAX_GNL_OP_RFKILL,
+		.flags = GENL_ADMIN_PERM,
+		.policy = wimax_gnl_policy,
+		.doit = wimax_gnl_doit_rfkill,
+	},
+	{
+		.cmd = WIMAX_GNL_OP_STATE_GET,
+		.flags = GENL_ADMIN_PERM,
+		.policy = wimax_gnl_policy,
+		.doit = wimax_gnl_doit_state_get,
+	},
 };
 
 
@@ -567,7 +589,7 @@ struct genl_multicast_group wimax_gnl_mcg = {
 static
 int __init wimax_subsys_init(void)
 {
-	int result, cnt;
+	int result;
 
 	d_fnstart(4, NULL, "()\n");
 	d_parse_params(D_LEVEL, D_LEVEL_SIZE, wimax_debug_params,
@@ -575,26 +597,14 @@ int __init wimax_subsys_init(void)
 
 	snprintf(wimax_gnl_family.name, sizeof(wimax_gnl_family.name),
 		 "WiMAX");
-	result = genl_register_family(&wimax_gnl_family);
+	result = genl_register_family_with_ops(&wimax_gnl_family, wimax_gnl_ops,
+					       ARRAY_SIZE(wimax_gnl_ops));
 	if (unlikely(result < 0)) {
 		printk(KERN_ERR "cannot register generic netlink family: %d\n",
 		       result);
 		goto error_register_family;
 	}
 
-	for (cnt = 0; cnt < ARRAY_SIZE(wimax_gnl_ops); cnt++) {
-		result = genl_register_ops(&wimax_gnl_family,
-					   wimax_gnl_ops[cnt]);
-		d_printf(4, NULL, "registering generic netlink op code "
-			 "%u: %d\n", wimax_gnl_ops[cnt]->cmd, result);
-		if (unlikely(result < 0)) {
-			printk(KERN_ERR "cannot register generic netlink op "
-			       "code %u: %d\n",
-			       wimax_gnl_ops[cnt]->cmd, result);
-			goto error_register_ops;
-		}
-	}
-
 	result = genl_register_mc_group(&wimax_gnl_family, &wimax_gnl_mcg);
 	if (result < 0)
 		goto error_mc_group;
@@ -602,10 +612,6 @@ int __init wimax_subsys_init(void)
 	return 0;
 
 error_mc_group:
-error_register_ops:
-	for (cnt--; cnt >= 0; cnt--)
-		genl_unregister_ops(&wimax_gnl_family,
-				    wimax_gnl_ops[cnt]);
 	genl_unregister_family(&wimax_gnl_family);
 error_register_family:
 	d_fnend(4, NULL, "() = %d\n", result);
@@ -619,12 +625,7 @@ module_init(wimax_subsys_init);
 static
 void __exit wimax_subsys_exit(void)
 {
-	int cnt;
 	wimax_id_table_release();
-	genl_unregister_mc_group(&wimax_gnl_family, &wimax_gnl_mcg);
-	for (cnt = ARRAY_SIZE(wimax_gnl_ops) - 1; cnt >= 0; cnt--)
-		genl_unregister_ops(&wimax_gnl_family,
-				    wimax_gnl_ops[cnt]);
 	genl_unregister_family(&wimax_gnl_family);
 }
 module_exit(wimax_subsys_exit);
diff --git a/net/wimax/wimax-internal.h b/net/wimax/wimax-internal.h
index 5dcd9c0..8567d30 100644
--- a/net/wimax/wimax-internal.h
+++ b/net/wimax/wimax-internal.h
@@ -84,8 +84,15 @@ void wimax_id_table_release(void);
 int wimax_rfkill_add(struct wimax_dev *);
 void wimax_rfkill_rm(struct wimax_dev *);
 
+/* generic netlink */
 extern struct genl_family wimax_gnl_family;
 extern struct genl_multicast_group wimax_gnl_mcg;
 
+/* ops */
+int wimax_gnl_doit_msg_from_user(struct sk_buff *skb, struct genl_info *info);
+int wimax_gnl_doit_reset(struct sk_buff *skb, struct genl_info *info);
+int wimax_gnl_doit_rfkill(struct sk_buff *skb, struct genl_info *info);
+int wimax_gnl_doit_state_get(struct sk_buff *skb, struct genl_info *info);
+
 #endif /* #ifdef __KERNEL__ */
 #endif /* #ifndef __WIMAX_INTERNAL_H__ */
-- 
1.8.4.rc3


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 5/9] genetlink: remove genl_register_ops/genl_unregister_ops
  2013-11-14 16:14 ` [PATCH 0/9] genetlink: reduce ops size and complexity (v2) Johannes Berg
                     ` (3 preceding siblings ...)
  2013-11-14 16:14   ` [PATCH 4/9] wimax: " Johannes Berg
@ 2013-11-14 16:14   ` Johannes Berg
  2013-11-14 16:14   ` [PATCH 6/9] genetlink: register family ops as array Johannes Berg
                     ` (4 subsequent siblings)
  9 siblings, 0 replies; 29+ messages in thread
From: Johannes Berg @ 2013-11-14 16:14 UTC (permalink / raw)
  To: netdev
  Cc: linux-wimax, Balbir Singh, netfilter-devel, Alexander Smirnov,
	Dmitry Eremin-Solenikov, Johannes Berg

From: Johannes Berg <johannes.berg@intel.com>

genl_register_ops() is still needed for internal registration,
but is no longer available to users of the API.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 include/net/genetlink.h |  2 --
 net/netlink/genetlink.c | 57 +------------------------------------------------
 2 files changed, 1 insertion(+), 58 deletions(-)

diff --git a/include/net/genetlink.h b/include/net/genetlink.h
index 9b787b6..617d718 100644
--- a/include/net/genetlink.h
+++ b/include/net/genetlink.h
@@ -141,8 +141,6 @@ static inline int genl_register_family_with_ops(struct genl_family *family,
 }
 
 int genl_unregister_family(struct genl_family *family);
-int genl_register_ops(struct genl_family *, struct genl_ops *ops);
-int genl_unregister_ops(struct genl_family *, struct genl_ops *ops);
 int genl_register_mc_group(struct genl_family *family,
 			   struct genl_multicast_group *grp);
 void genl_unregister_mc_group(struct genl_family *family,
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index 0c741ce..fbccb45 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -283,22 +283,7 @@ static void genl_unregister_mc_groups(struct genl_family *family)
 		__genl_unregister_mc_group(family, grp);
 }
 
-/**
- * genl_register_ops - register generic netlink operations
- * @family: generic netlink family
- * @ops: operations to be registered
- *
- * Registers the specified operations and assigns them to the specified
- * family. Either a doit or dumpit callback must be specified or the
- * operation will fail. Only one operation structure per command
- * identifier may be registered.
- *
- * See include/net/genetlink.h for more documenation on the operations
- * structure.
- *
- * Returns 0 on success or a negative error code.
- */
-int genl_register_ops(struct genl_family *family, struct genl_ops *ops)
+static int genl_register_ops(struct genl_family *family, struct genl_ops *ops)
 {
 	int err = -EINVAL;
 
@@ -326,42 +311,6 @@ int genl_register_ops(struct genl_family *family, struct genl_ops *ops)
 errout:
 	return err;
 }
-EXPORT_SYMBOL(genl_register_ops);
-
-/**
- * genl_unregister_ops - unregister generic netlink operations
- * @family: generic netlink family
- * @ops: operations to be unregistered
- *
- * Unregisters the specified operations and unassigns them from the
- * specified family. The operation blocks until the current message
- * processing has finished and doesn't start again until the
- * unregister process has finished.
- *
- * Note: It is not necessary to unregister all operations before
- *       unregistering the family, unregistering the family will cause
- *       all assigned operations to be unregistered automatically.
- *
- * Returns 0 on success or a negative error code.
- */
-int genl_unregister_ops(struct genl_family *family, struct genl_ops *ops)
-{
-	struct genl_ops *rc;
-
-	genl_lock_all();
-	list_for_each_entry(rc, &family->ops_list, ops_list) {
-		if (rc == ops) {
-			list_del(&ops->ops_list);
-			genl_unlock_all();
-			genl_ctrl_event(CTRL_CMD_DELOPS, ops);
-			return 0;
-		}
-	}
-	genl_unlock_all();
-
-	return -ENOENT;
-}
-EXPORT_SYMBOL(genl_unregister_ops);
 
 /**
  * __genl_register_family - register a generic netlink family
@@ -451,10 +400,6 @@ EXPORT_SYMBOL(__genl_register_family);
  * See include/net/genetlink.h for more documenation on the operations
  * structure.
  *
- * This is equivalent to calling genl_register_family() followed by
- * genl_register_ops() for every operation entry in the table taking
- * care to unregister the family on error path.
- *
  * Return 0 on success or a negative error code.
  */
 int __genl_register_family_with_ops(struct genl_family *family,
-- 
1.8.4.rc3

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 6/9] genetlink: register family ops as array
  2013-11-14 16:14 ` [PATCH 0/9] genetlink: reduce ops size and complexity (v2) Johannes Berg
                     ` (4 preceding siblings ...)
  2013-11-14 16:14   ` [PATCH 5/9] genetlink: remove genl_register_ops/genl_unregister_ops Johannes Berg
@ 2013-11-14 16:14   ` Johannes Berg
  2013-11-14 16:14   ` [PATCH 7/9] genetlink: allow making ops const Johannes Berg
                     ` (3 subsequent siblings)
  9 siblings, 0 replies; 29+ messages in thread
From: Johannes Berg @ 2013-11-14 16:14 UTC (permalink / raw)
  To: netdev
  Cc: linux-wimax, Balbir Singh, netfilter-devel, Alexander Smirnov,
	Dmitry Eremin-Solenikov, Johannes Berg

From: Johannes Berg <johannes.berg@intel.com>

Instead of using a linked list, use an array. This reduces
the data size needed by the users of genetlink, for example
in wireless (net/wireless/nl80211.c) on 64-bit it frees up
over 1K of data space.

Remove the attempted sending of CTRL_CMD_NEWOPS ctrl event
since genl_ctrl_event(CTRL_CMD_NEWOPS, ...) only returns
-EINVAL anyway, therefore no such event could ever be sent.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 include/net/genetlink.h |  7 +++--
 net/netlink/genetlink.c | 78 +++++++++++++++++++++----------------------------
 2 files changed, 37 insertions(+), 48 deletions(-)

diff --git a/include/net/genetlink.h b/include/net/genetlink.h
index 617d718..d4802af 100644
--- a/include/net/genetlink.h
+++ b/include/net/genetlink.h
@@ -39,9 +39,10 @@ struct genl_info;
  * @post_doit: called after an operation's doit callback, it may
  *	undo operations done by pre_doit, for example release locks
  * @attrbuf: buffer to store parsed attributes
- * @ops_list: list of all assigned operations
  * @family_list: family list
  * @mcast_groups: multicast groups list
+ * @ops: the operations supported by this family (private)
+ * @n_ops: number of operations supported by this family (private)
  */
 struct genl_family {
 	unsigned int		id;
@@ -58,7 +59,8 @@ struct genl_family {
 					     struct sk_buff *skb,
 					     struct genl_info *info);
 	struct nlattr **	attrbuf;	/* private */
-	struct list_head	ops_list;	/* private */
+	struct genl_ops *	ops;		/* private */
+	unsigned int		n_ops;		/* private */
 	struct list_head	family_list;	/* private */
 	struct list_head	mcast_groups;	/* private */
 	struct module		*module;
@@ -119,7 +121,6 @@ struct genl_ops {
 	int		       (*dumpit)(struct sk_buff *skb,
 					 struct netlink_callback *cb);
 	int		       (*done)(struct netlink_callback *cb);
-	struct list_head	ops_list;
 };
 
 int __genl_register_family(struct genl_family *family);
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index fbccb45..d8273b0 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -108,11 +108,11 @@ static struct genl_family *genl_family_find_byname(char *name)
 
 static struct genl_ops *genl_get_cmd(u8 cmd, struct genl_family *family)
 {
-	struct genl_ops *ops;
+	int i;
 
-	list_for_each_entry(ops, &family->ops_list, ops_list)
-		if (ops->cmd == cmd)
-			return ops;
+	for (i = 0; i < family->n_ops; i++)
+		if (family->ops[i].cmd == cmd)
+			return &family->ops[i];
 
 	return NULL;
 }
@@ -283,33 +283,30 @@ static void genl_unregister_mc_groups(struct genl_family *family)
 		__genl_unregister_mc_group(family, grp);
 }
 
-static int genl_register_ops(struct genl_family *family, struct genl_ops *ops)
+static int genl_validate_add_ops(struct genl_family *family, struct genl_ops *ops,
+				 unsigned int n_ops)
 {
-	int err = -EINVAL;
-
-	if (ops->dumpit == NULL && ops->doit == NULL)
-		goto errout;
-
-	if (genl_get_cmd(ops->cmd, family)) {
-		err = -EEXIST;
-		goto errout;
+	int i, j;
+
+	for (i = 0; i < n_ops; i++) {
+		if (ops[i].dumpit == NULL && ops[i].doit == NULL)
+			return -EINVAL;
+		for (j = i + 1; j < n_ops; j++)
+			if (ops[i].cmd == ops[j].cmd)
+				return -EINVAL;
+		if (ops[i].dumpit)
+			ops[i].flags |= GENL_CMD_CAP_DUMP;
+		if (ops[i].doit)
+			ops[i].flags |= GENL_CMD_CAP_DO;
+		if (ops[i].policy)
+			ops[i].flags |= GENL_CMD_CAP_HASPOL;
 	}
 
-	if (ops->dumpit)
-		ops->flags |= GENL_CMD_CAP_DUMP;
-	if (ops->doit)
-		ops->flags |= GENL_CMD_CAP_DO;
-	if (ops->policy)
-		ops->flags |= GENL_CMD_CAP_HASPOL;
-
-	genl_lock_all();
-	list_add_tail(&ops->ops_list, &family->ops_list);
-	genl_unlock_all();
+	/* family is not registered yet, so no locking needed */
+	family->ops = ops;
+	family->n_ops = n_ops;
 
-	genl_ctrl_event(CTRL_CMD_NEWOPS, ops);
-	err = 0;
-errout:
-	return err;
+	return 0;
 }
 
 /**
@@ -333,7 +330,6 @@ int __genl_register_family(struct genl_family *family)
 	if (family->id > GENL_MAX_ID)
 		goto errout;
 
-	INIT_LIST_HEAD(&family->ops_list);
 	INIT_LIST_HEAD(&family->mcast_groups);
 
 	genl_lock_all();
@@ -405,21 +401,13 @@ EXPORT_SYMBOL(__genl_register_family);
 int __genl_register_family_with_ops(struct genl_family *family,
 	struct genl_ops *ops, size_t n_ops)
 {
-	int err, i;
+	int err;
 
-	err = __genl_register_family(family);
+	err = genl_validate_add_ops(family, ops, n_ops);
 	if (err)
 		return err;
 
-	for (i = 0; i < n_ops; ++i, ++ops) {
-		err = genl_register_ops(family, ops);
-		if (err)
-			goto err_out;
-	}
-	return 0;
-err_out:
-	genl_unregister_family(family);
-	return err;
+	return __genl_register_family(family);
 }
 EXPORT_SYMBOL(__genl_register_family_with_ops);
 
@@ -444,7 +432,7 @@ int genl_unregister_family(struct genl_family *family)
 			continue;
 
 		list_del(&rc->family_list);
-		INIT_LIST_HEAD(&family->ops_list);
+		family->n_ops = 0;
 		genl_unlock_all();
 
 		kfree(family->attrbuf);
@@ -671,19 +659,19 @@ static int ctrl_fill_info(struct genl_family *family, u32 portid, u32 seq,
 	    nla_put_u32(skb, CTRL_ATTR_MAXATTR, family->maxattr))
 		goto nla_put_failure;
 
-	if (!list_empty(&family->ops_list)) {
+	if (family->n_ops) {
 		struct nlattr *nla_ops;
-		struct genl_ops *ops;
-		int idx = 1;
+		int i;
 
 		nla_ops = nla_nest_start(skb, CTRL_ATTR_OPS);
 		if (nla_ops == NULL)
 			goto nla_put_failure;
 
-		list_for_each_entry(ops, &family->ops_list, ops_list) {
+		for (i = 0; i < family->n_ops; i++) {
 			struct nlattr *nest;
+			struct genl_ops *ops = &family->ops[i];
 
-			nest = nla_nest_start(skb, idx++);
+			nest = nla_nest_start(skb, i + 1);
 			if (nest == NULL)
 				goto nla_put_failure;
 
-- 
1.8.4.rc3

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 7/9] genetlink: allow making ops const
  2013-11-14 16:14 ` [PATCH 0/9] genetlink: reduce ops size and complexity (v2) Johannes Berg
                     ` (5 preceding siblings ...)
  2013-11-14 16:14   ` [PATCH 6/9] genetlink: register family ops as array Johannes Berg
@ 2013-11-14 16:14   ` Johannes Berg
  2013-11-14 16:14   ` [PATCH 8/9] genetlink: make all genl_ops users const Johannes Berg
                     ` (2 subsequent siblings)
  9 siblings, 0 replies; 29+ messages in thread
From: Johannes Berg @ 2013-11-14 16:14 UTC (permalink / raw)
  To: netdev
  Cc: linux-wimax, Balbir Singh, netfilter-devel, Alexander Smirnov,
	Dmitry Eremin-Solenikov, Johannes Berg

From: Johannes Berg <johannes.berg@intel.com>

Allow making the ops array const by not modifying the ops
flags on registration but rather only when ops are sent
out in the family information.

No users are updated yet except for the pre_doit/post_doit
calls in wireless (the only ones that exist now.)

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 include/net/genetlink.h | 10 +++++-----
 net/netlink/genetlink.c | 36 +++++++++++++++++++++---------------
 net/wireless/nl80211.c  |  8 ++++----
 3 files changed, 30 insertions(+), 24 deletions(-)

diff --git a/include/net/genetlink.h b/include/net/genetlink.h
index d4802af..d87486a 100644
--- a/include/net/genetlink.h
+++ b/include/net/genetlink.h
@@ -52,14 +52,14 @@ struct genl_family {
 	unsigned int		maxattr;
 	bool			netnsok;
 	bool			parallel_ops;
-	int			(*pre_doit)(struct genl_ops *ops,
+	int			(*pre_doit)(const struct genl_ops *ops,
 					    struct sk_buff *skb,
 					    struct genl_info *info);
-	void			(*post_doit)(struct genl_ops *ops,
+	void			(*post_doit)(const struct genl_ops *ops,
 					     struct sk_buff *skb,
 					     struct genl_info *info);
 	struct nlattr **	attrbuf;	/* private */
-	struct genl_ops *	ops;		/* private */
+	const struct genl_ops *	ops;		/* private */
 	unsigned int		n_ops;		/* private */
 	struct list_head	family_list;	/* private */
 	struct list_head	mcast_groups;	/* private */
@@ -132,10 +132,10 @@ static inline int genl_register_family(struct genl_family *family)
 }
 
 int __genl_register_family_with_ops(struct genl_family *family,
-				    struct genl_ops *ops, size_t n_ops);
+				    const struct genl_ops *ops, size_t n_ops);
 
 static inline int genl_register_family_with_ops(struct genl_family *family,
-	struct genl_ops *ops, size_t n_ops)
+	const struct genl_ops *ops, size_t n_ops)
 {
 	family->module = THIS_MODULE;
 	return __genl_register_family_with_ops(family, ops, n_ops);
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index d8273b0..a7c62d3 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -106,7 +106,7 @@ static struct genl_family *genl_family_find_byname(char *name)
 	return NULL;
 }
 
-static struct genl_ops *genl_get_cmd(u8 cmd, struct genl_family *family)
+static const struct genl_ops *genl_get_cmd(u8 cmd, struct genl_family *family)
 {
 	int i;
 
@@ -283,7 +283,8 @@ static void genl_unregister_mc_groups(struct genl_family *family)
 		__genl_unregister_mc_group(family, grp);
 }
 
-static int genl_validate_add_ops(struct genl_family *family, struct genl_ops *ops,
+static int genl_validate_add_ops(struct genl_family *family,
+				 const struct genl_ops *ops,
 				 unsigned int n_ops)
 {
 	int i, j;
@@ -294,12 +295,6 @@ static int genl_validate_add_ops(struct genl_family *family, struct genl_ops *op
 		for (j = i + 1; j < n_ops; j++)
 			if (ops[i].cmd == ops[j].cmd)
 				return -EINVAL;
-		if (ops[i].dumpit)
-			ops[i].flags |= GENL_CMD_CAP_DUMP;
-		if (ops[i].doit)
-			ops[i].flags |= GENL_CMD_CAP_DO;
-		if (ops[i].policy)
-			ops[i].flags |= GENL_CMD_CAP_HASPOL;
 	}
 
 	/* family is not registered yet, so no locking needed */
@@ -399,7 +394,7 @@ EXPORT_SYMBOL(__genl_register_family);
  * Return 0 on success or a negative error code.
  */
 int __genl_register_family_with_ops(struct genl_family *family,
-	struct genl_ops *ops, size_t n_ops)
+	const struct genl_ops *ops, size_t n_ops)
 {
 	int err;
 
@@ -479,7 +474,8 @@ EXPORT_SYMBOL(genlmsg_put);
 
 static int genl_lock_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
 {
-	struct genl_ops *ops = cb->data;
+	/* our ops are always const - netlink API doesn't propagate that */
+	const struct genl_ops *ops = cb->data;
 	int rc;
 
 	genl_lock();
@@ -490,7 +486,8 @@ static int genl_lock_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
 
 static int genl_lock_done(struct netlink_callback *cb)
 {
-	struct genl_ops *ops = cb->data;
+	/* our ops are always const - netlink API doesn't propagate that */
+	const struct genl_ops *ops = cb->data;
 	int rc = 0;
 
 	if (ops->done) {
@@ -505,7 +502,7 @@ static int genl_family_rcv_msg(struct genl_family *family,
 			       struct sk_buff *skb,
 			       struct nlmsghdr *nlh)
 {
-	struct genl_ops *ops;
+	const struct genl_ops *ops;
 	struct net *net = sock_net(skb->sk);
 	struct genl_info info;
 	struct genlmsghdr *hdr = nlmsg_data(nlh);
@@ -537,7 +534,8 @@ static int genl_family_rcv_msg(struct genl_family *family,
 		if (!family->parallel_ops) {
 			struct netlink_dump_control c = {
 				.module = family->module,
-				.data = ops,
+				/* we have const, but the netlink API doesn't */
+				.data = (void *)ops,
 				.dump = genl_lock_dumpit,
 				.done = genl_lock_done,
 			};
@@ -669,14 +667,22 @@ static int ctrl_fill_info(struct genl_family *family, u32 portid, u32 seq,
 
 		for (i = 0; i < family->n_ops; i++) {
 			struct nlattr *nest;
-			struct genl_ops *ops = &family->ops[i];
+			const struct genl_ops *ops = &family->ops[i];
+			u32 flags = ops->flags;
+
+			if (ops->dumpit)
+				flags |= GENL_CMD_CAP_DUMP;
+			if (ops->doit)
+				flags |= GENL_CMD_CAP_DO;
+			if (ops->policy)
+				flags |= GENL_CMD_CAP_HASPOL;
 
 			nest = nla_nest_start(skb, i + 1);
 			if (nest == NULL)
 				goto nla_put_failure;
 
 			if (nla_put_u32(skb, CTRL_ATTR_OP_ID, ops->cmd) ||
-			    nla_put_u32(skb, CTRL_ATTR_OP_FLAGS, ops->flags))
+			    nla_put_u32(skb, CTRL_ATTR_OP_FLAGS, flags))
 				goto nla_put_failure;
 
 			nla_nest_end(skb, nest);
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index a7f4e79..3fef559 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -30,9 +30,9 @@ static int nl80211_crypto_settings(struct cfg80211_registered_device *rdev,
 				   struct cfg80211_crypto_settings *settings,
 				   int cipher_limit);
 
-static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb,
+static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
 			    struct genl_info *info);
-static void nl80211_post_doit(struct genl_ops *ops, struct sk_buff *skb,
+static void nl80211_post_doit(const struct genl_ops *ops, struct sk_buff *skb,
 			      struct genl_info *info);
 
 /* the netlink family */
@@ -8851,7 +8851,7 @@ static int nl80211_crit_protocol_stop(struct sk_buff *skb,
 #define NL80211_FLAG_NEED_WDEV_UP	(NL80211_FLAG_NEED_WDEV |\
 					 NL80211_FLAG_CHECK_NETDEV_UP)
 
-static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb,
+static int nl80211_pre_doit(const struct genl_ops *ops, struct sk_buff *skb,
 			    struct genl_info *info)
 {
 	struct cfg80211_registered_device *rdev;
@@ -8920,7 +8920,7 @@ static int nl80211_pre_doit(struct genl_ops *ops, struct sk_buff *skb,
 	return 0;
 }
 
-static void nl80211_post_doit(struct genl_ops *ops, struct sk_buff *skb,
+static void nl80211_post_doit(const struct genl_ops *ops, struct sk_buff *skb,
 			      struct genl_info *info)
 {
 	if (info->user_ptr[1]) {
-- 
1.8.4.rc3

^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 8/9] genetlink: make all genl_ops users const
  2013-11-14 16:14 ` [PATCH 0/9] genetlink: reduce ops size and complexity (v2) Johannes Berg
                     ` (6 preceding siblings ...)
  2013-11-14 16:14   ` [PATCH 7/9] genetlink: allow making ops const Johannes Berg
@ 2013-11-14 16:14   ` Johannes Berg
  2013-11-14 16:14   ` [PATCH 9/9] genetlink: make genl_ops flags a u8 and move to end Johannes Berg
  2013-11-14 22:12   ` [PATCH 0/9] genetlink: reduce ops size and complexity (v2) David Miller
  9 siblings, 0 replies; 29+ messages in thread
From: Johannes Berg @ 2013-11-14 16:14 UTC (permalink / raw)
  To: netdev
  Cc: linux-wimax, Balbir Singh, netfilter-devel, Alexander Smirnov,
	Dmitry Eremin-Solenikov, Johannes Berg

From: Johannes Berg <johannes.berg@intel.com>

Now that genl_ops are no longer modified in place when
registering, they can be made const. This patch was done
mostly with spatch:

@@
identifier ops;
@@
+const
 struct genl_ops ops[] = {
 ...
 };

(except the struct thing in net/openvswitch/datapath.c)

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 drivers/net/team/team.c               |  2 +-
 drivers/net/wireless/mac80211_hwsim.c |  2 +-
 kernel/taskstats.c                    |  2 +-
 net/core/drop_monitor.c               |  2 +-
 net/hsr/hsr_netlink.c                 |  2 +-
 net/ieee802154/netlink.c              |  2 +-
 net/ipv4/tcp_metrics.c                |  2 +-
 net/irda/irnetlink.c                  |  2 +-
 net/l2tp/l2tp_netlink.c               |  2 +-
 net/netfilter/ipvs/ip_vs_ctl.c        |  2 +-
 net/netlabel/netlabel_cipso_v4.c      |  2 +-
 net/netlabel/netlabel_mgmt.c          |  2 +-
 net/netlabel/netlabel_unlabeled.c     |  2 +-
 net/nfc/netlink.c                     |  2 +-
 net/openvswitch/datapath.c            | 10 +++++-----
 net/wimax/stack.c                     |  2 +-
 net/wireless/nl80211.c                |  2 +-
 17 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
index 50e43e6..6390254 100644
--- a/drivers/net/team/team.c
+++ b/drivers/net/team/team.c
@@ -2644,7 +2644,7 @@ static int team_nl_cmd_port_list_get(struct sk_buff *skb,
 	return err;
 }
 
-static struct genl_ops team_nl_ops[] = {
+static const struct genl_ops team_nl_ops[] = {
 	{
 		.cmd = TEAM_CMD_NOOP,
 		.doit = team_nl_cmd_noop,
diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
index de0df86..cfc3fda 100644
--- a/drivers/net/wireless/mac80211_hwsim.c
+++ b/drivers/net/wireless/mac80211_hwsim.c
@@ -2097,7 +2097,7 @@ out:
 }
 
 /* Generic Netlink operations array */
-static struct genl_ops hwsim_ops[] = {
+static const struct genl_ops hwsim_ops[] = {
 	{
 		.cmd = HWSIM_CMD_REGISTER,
 		.policy = hwsim_genl_policy,
diff --git a/kernel/taskstats.c b/kernel/taskstats.c
index 609e77f..76595cd 100644
--- a/kernel/taskstats.c
+++ b/kernel/taskstats.c
@@ -673,7 +673,7 @@ err:
 	nlmsg_free(rep_skb);
 }
 
-static struct genl_ops taskstats_ops[] = {
+static const struct genl_ops taskstats_ops[] = {
 	{
 		.cmd		= TASKSTATS_CMD_GET,
 		.doit		= taskstats_user_cmd,
diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c
index 5e78d44..f9fe2f2 100644
--- a/net/core/drop_monitor.c
+++ b/net/core/drop_monitor.c
@@ -333,7 +333,7 @@ out:
 	return NOTIFY_DONE;
 }
 
-static struct genl_ops dropmon_ops[] = {
+static const struct genl_ops dropmon_ops[] = {
 	{
 		.cmd = NET_DM_CMD_CONFIG,
 		.doit = net_dm_cmd_config,
diff --git a/net/hsr/hsr_netlink.c b/net/hsr/hsr_netlink.c
index 8f52a9f..79d72ca 100644
--- a/net/hsr/hsr_netlink.c
+++ b/net/hsr/hsr_netlink.c
@@ -389,7 +389,7 @@ fail:
 }
 
 
-static struct genl_ops hsr_ops[] = {
+static const struct genl_ops hsr_ops[] = {
 	{
 		.cmd = HSR_C_GET_NODE_STATUS,
 		.flags = 0,
diff --git a/net/ieee802154/netlink.c b/net/ieee802154/netlink.c
index eb9faef..3ffcdbb 100644
--- a/net/ieee802154/netlink.c
+++ b/net/ieee802154/netlink.c
@@ -109,7 +109,7 @@ out:
 	return -ENOBUFS;
 }
 
-static struct genl_ops ieee8021154_ops[] = {
+static const struct genl_ops ieee8021154_ops[] = {
 	/* see nl-phy.c */
 	IEEE802154_DUMP(IEEE802154_LIST_PHY, ieee802154_list_phy,
 			ieee802154_dump_phy),
diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c
index 2ab09cb..9b780c1 100644
--- a/net/ipv4/tcp_metrics.c
+++ b/net/ipv4/tcp_metrics.c
@@ -988,7 +988,7 @@ static int tcp_metrics_nl_cmd_del(struct sk_buff *skb, struct genl_info *info)
 	return 0;
 }
 
-static struct genl_ops tcp_metrics_nl_ops[] = {
+static const struct genl_ops tcp_metrics_nl_ops[] = {
 	{
 		.cmd = TCP_METRICS_CMD_GET,
 		.doit = tcp_metrics_nl_cmd_get,
diff --git a/net/irda/irnetlink.c b/net/irda/irnetlink.c
index c3297126..bf5d7d4 100644
--- a/net/irda/irnetlink.c
+++ b/net/irda/irnetlink.c
@@ -131,7 +131,7 @@ static const struct nla_policy irda_nl_policy[IRDA_NL_ATTR_MAX + 1] = {
 	[IRDA_NL_ATTR_MODE] = { .type = NLA_U32 },
 };
 
-static struct genl_ops irda_nl_ops[] = {
+static const struct genl_ops irda_nl_ops[] = {
 	{
 		.cmd = IRDA_NL_CMD_SET_MODE,
 		.doit = irda_nl_set_mode,
diff --git a/net/l2tp/l2tp_netlink.c b/net/l2tp/l2tp_netlink.c
index be446d5..57db66e 100644
--- a/net/l2tp/l2tp_netlink.c
+++ b/net/l2tp/l2tp_netlink.c
@@ -793,7 +793,7 @@ static struct nla_policy l2tp_nl_policy[L2TP_ATTR_MAX + 1] = {
 	},
 };
 
-static struct genl_ops l2tp_nl_ops[] = {
+static const struct genl_ops l2tp_nl_ops[] = {
 	{
 		.cmd = L2TP_CMD_NOOP,
 		.doit = l2tp_nl_cmd_noop,
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index 62786a4..fc8a04e 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -3567,7 +3567,7 @@ out:
 }
 
 
-static struct genl_ops ip_vs_genl_ops[] __read_mostly = {
+static const struct genl_ops ip_vs_genl_ops[] __read_mostly = {
 	{
 		.cmd	= IPVS_CMD_NEW_SERVICE,
 		.flags	= GENL_ADMIN_PERM,
diff --git a/net/netlabel/netlabel_cipso_v4.c b/net/netlabel/netlabel_cipso_v4.c
index a110064..7066917 100644
--- a/net/netlabel/netlabel_cipso_v4.c
+++ b/net/netlabel/netlabel_cipso_v4.c
@@ -737,7 +737,7 @@ static int netlbl_cipsov4_remove(struct sk_buff *skb, struct genl_info *info)
  * NetLabel Generic NETLINK Command Definitions
  */
 
-static struct genl_ops netlbl_cipsov4_ops[] = {
+static const struct genl_ops netlbl_cipsov4_ops[] = {
 	{
 	.cmd = NLBL_CIPSOV4_C_ADD,
 	.flags = GENL_ADMIN_PERM,
diff --git a/net/netlabel/netlabel_mgmt.c b/net/netlabel/netlabel_mgmt.c
index dd1c37d..7de6f66 100644
--- a/net/netlabel/netlabel_mgmt.c
+++ b/net/netlabel/netlabel_mgmt.c
@@ -705,7 +705,7 @@ version_failure:
  * NetLabel Generic NETLINK Command Definitions
  */
 
-static struct genl_ops netlbl_mgmt_genl_ops[] = {
+static const struct genl_ops netlbl_mgmt_genl_ops[] = {
 	{
 	.cmd = NLBL_MGMT_C_ADD,
 	.flags = GENL_ADMIN_PERM,
diff --git a/net/netlabel/netlabel_unlabeled.c b/net/netlabel/netlabel_unlabeled.c
index 8f08974..76ee925 100644
--- a/net/netlabel/netlabel_unlabeled.c
+++ b/net/netlabel/netlabel_unlabeled.c
@@ -1323,7 +1323,7 @@ unlabel_staticlistdef_return:
  * NetLabel Generic NETLINK Command Definitions
  */
 
-static struct genl_ops netlbl_unlabel_genl_ops[] = {
+static const struct genl_ops netlbl_unlabel_genl_ops[] = {
 	{
 	.cmd = NLBL_UNLABEL_C_STATICADD,
 	.flags = GENL_ADMIN_PERM,
diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c
index 84b7e3e..f558561 100644
--- a/net/nfc/netlink.c
+++ b/net/nfc/netlink.c
@@ -1364,7 +1364,7 @@ static int nfc_genl_se_io(struct sk_buff *skb, struct genl_info *info)
 	return dev->ops->se_io(dev, se_idx, apdu, apdu_len, se_io_cb, ctx);
 }
 
-static struct genl_ops nfc_genl_ops[] = {
+static const struct genl_ops nfc_genl_ops[] = {
 	{
 		.cmd = NFC_CMD_GET_DEVICE,
 		.doit = nfc_genl_get_device,
diff --git a/net/openvswitch/datapath.c b/net/openvswitch/datapath.c
index 1408adc..91e1c92 100644
--- a/net/openvswitch/datapath.c
+++ b/net/openvswitch/datapath.c
@@ -557,7 +557,7 @@ static const struct nla_policy packet_policy[OVS_PACKET_ATTR_MAX + 1] = {
 	[OVS_PACKET_ATTR_ACTIONS] = { .type = NLA_NESTED },
 };
 
-static struct genl_ops dp_packet_genl_ops[] = {
+static const struct genl_ops dp_packet_genl_ops[] = {
 	{ .cmd = OVS_PACKET_CMD_EXECUTE,
 	  .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
 	  .policy = packet_policy,
@@ -1034,7 +1034,7 @@ static int ovs_flow_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb)
 	return skb->len;
 }
 
-static struct genl_ops dp_flow_genl_ops[] = {
+static const struct genl_ops dp_flow_genl_ops[] = {
 	{ .cmd = OVS_FLOW_CMD_NEW,
 	  .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
 	  .policy = flow_policy,
@@ -1392,7 +1392,7 @@ static int ovs_dp_cmd_dump(struct sk_buff *skb, struct netlink_callback *cb)
 	return skb->len;
 }
 
-static struct genl_ops dp_datapath_genl_ops[] = {
+static const struct genl_ops dp_datapath_genl_ops[] = {
 	{ .cmd = OVS_DP_CMD_NEW,
 	  .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
 	  .policy = datapath_policy,
@@ -1753,7 +1753,7 @@ out:
 	return skb->len;
 }
 
-static struct genl_ops dp_vport_genl_ops[] = {
+static const struct genl_ops dp_vport_genl_ops[] = {
 	{ .cmd = OVS_VPORT_CMD_NEW,
 	  .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN privilege. */
 	  .policy = vport_policy,
@@ -1779,7 +1779,7 @@ static struct genl_ops dp_vport_genl_ops[] = {
 
 struct genl_family_and_ops {
 	struct genl_family *family;
-	struct genl_ops *ops;
+	const struct genl_ops *ops;
 	int n_ops;
 	struct genl_multicast_group *group;
 };
diff --git a/net/wimax/stack.c b/net/wimax/stack.c
index 4b7f15a..47170c9 100644
--- a/net/wimax/stack.c
+++ b/net/wimax/stack.c
@@ -415,7 +415,7 @@ static const struct nla_policy wimax_gnl_policy[WIMAX_GNL_ATTR_MAX + 1] = {
 	},
 };
 
-static struct genl_ops wimax_gnl_ops[] = {
+static const struct genl_ops wimax_gnl_ops[] = {
 	{
 		.cmd = WIMAX_GNL_OP_MSG_FROM_USER,
 		.flags = GENL_ADMIN_PERM,
diff --git a/net/wireless/nl80211.c b/net/wireless/nl80211.c
index 3fef559..58c43c8 100644
--- a/net/wireless/nl80211.c
+++ b/net/wireless/nl80211.c
@@ -8937,7 +8937,7 @@ static void nl80211_post_doit(const struct genl_ops *ops, struct sk_buff *skb,
 		rtnl_unlock();
 }
 
-static struct genl_ops nl80211_ops[] = {
+static const struct genl_ops nl80211_ops[] = {
 	{
 		.cmd = NL80211_CMD_GET_WIPHY,
 		.doit = nl80211_get_wiphy,
-- 
1.8.4.rc3


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* [PATCH 9/9] genetlink: make genl_ops flags a u8 and move to end
  2013-11-14 16:14 ` [PATCH 0/9] genetlink: reduce ops size and complexity (v2) Johannes Berg
                     ` (7 preceding siblings ...)
  2013-11-14 16:14   ` [PATCH 8/9] genetlink: make all genl_ops users const Johannes Berg
@ 2013-11-14 16:14   ` Johannes Berg
  2013-11-14 22:12   ` [PATCH 0/9] genetlink: reduce ops size and complexity (v2) David Miller
  9 siblings, 0 replies; 29+ messages in thread
From: Johannes Berg @ 2013-11-14 16:14 UTC (permalink / raw)
  To: netdev
  Cc: linux-wimax, Balbir Singh, netfilter-devel, Alexander Smirnov,
	Dmitry Eremin-Solenikov, Johannes Berg

From: Johannes Berg <johannes.berg@intel.com>

To save some space in the struct on 32-bit systems,
make the flags a u8 (only 4 bits are used) and also
move them to the end of the struct.

This has no impact on 64-bit systems as alignment of
the struct in an array uses up the space anyway.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
 include/net/genetlink.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/include/net/genetlink.h b/include/net/genetlink.h
index d87486a..0b6a144 100644
--- a/include/net/genetlink.h
+++ b/include/net/genetlink.h
@@ -112,15 +112,15 @@ static inline void genl_info_net_set(struct genl_info *info, struct net *net)
  * @ops_list: operations list
  */
 struct genl_ops {
-	u8			cmd;
-	u8			internal_flags;
-	unsigned int		flags;
 	const struct nla_policy	*policy;
 	int		       (*doit)(struct sk_buff *skb,
 				       struct genl_info *info);
 	int		       (*dumpit)(struct sk_buff *skb,
 					 struct netlink_callback *cb);
 	int		       (*done)(struct netlink_callback *cb);
+	u8			cmd;
+	u8			internal_flags;
+	u8			flags;
 };
 
 int __genl_register_family(struct genl_family *family);
-- 
1.8.4.rc3


^ permalink raw reply related	[flat|nested] 29+ messages in thread

* Re: [PATCH 0/9] genetlink: reduce ops size and complexity (v2)
  2013-11-14 16:14 ` [PATCH 0/9] genetlink: reduce ops size and complexity (v2) Johannes Berg
                     ` (8 preceding siblings ...)
  2013-11-14 16:14   ` [PATCH 9/9] genetlink: make genl_ops flags a u8 and move to end Johannes Berg
@ 2013-11-14 22:12   ` David Miller
  2013-11-15 13:18     ` Johannes Berg
  9 siblings, 1 reply; 29+ messages in thread
From: David Miller @ 2013-11-14 22:12 UTC (permalink / raw)
  To: johannes
  Cc: netdev, linux-wimax, bsingharora, netfilter-devel,
	alex.bluesman.smirnov, dbaryshkov

From: Johannes Berg <johannes@sipsolutions.net>
Date: Thu, 14 Nov 2013 17:14:38 +0100

> As before - reduce the complexity and data/code size of genetlink ops
> by making them an array rather than a linked list. Most users already
> use an array thanks to genl_register_family_with_ops(), so convert the
> remaining ones allowing us to get rid of the list head in each op.
> 
> Also make them const, this just makes sense at that point and the security
> people like making function pointers const as well :-)

I have to say, this is an absolutely fantastic space usage and
complexity improvement.

Applied, thanks a lot.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 0/9] genetlink: reduce ops size and complexity (v2)
  2013-11-14 22:12   ` [PATCH 0/9] genetlink: reduce ops size and complexity (v2) David Miller
@ 2013-11-15 13:18     ` Johannes Berg
  2013-11-15 13:23       ` Johannes Berg
  2013-11-16  1:53       ` David Miller
  0 siblings, 2 replies; 29+ messages in thread
From: Johannes Berg @ 2013-11-15 13:18 UTC (permalink / raw)
  To: David Miller
  Cc: netdev, linux-wimax, bsingharora, netfilter-devel,
	alex.bluesman.smirnov, dbaryshkov

On Thu, 2013-11-14 at 17:12 -0500, David Miller wrote:
> From: Johannes Berg <johannes@sipsolutions.net>
> Date: Thu, 14 Nov 2013 17:14:38 +0100
> 
> > As before - reduce the complexity and data/code size of genetlink ops
> > by making them an array rather than a linked list. Most users already
> > use an array thanks to genl_register_family_with_ops(), so convert the
> > remaining ones allowing us to get rid of the list head in each op.
> > 
> > Also make them const, this just makes sense at that point and the security
> > people like making function pointers const as well :-)
> 
> I have to say, this is an absolutely fantastic space usage and
> complexity improvement.

:-)

FWIW, we can also clean up the two registration functions now and make
it just a single one (actually we could have done that before as well,
passing NULL for ops, but hey, now it's even easier). I'll send a patch
for that.

I've been eyeing the multicast groups as well, but the code using them
is nicer if it's not an array. With an array, you'd have to do something
like

send_event(&my_mcast_groups[1]);

instead of

send_event(&my_foo_mcast_group);

which is a bit odd.

We could instead register an array of pointers to the groups:

static const struct mcast_group *my_groups[] = {
	&my_foo_mcast_group,
	...
};

and pass this to the family - that'd still be less space (one pointer
for each group rather than two in a linked list) and still allow all
groups and this array to be const, but it's not quite as big a
saving ...

Thoughts?

johannes



^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 0/9] genetlink: reduce ops size and complexity (v2)
  2013-11-15 13:18     ` Johannes Berg
@ 2013-11-15 13:23       ` Johannes Berg
  2013-11-15 14:45         ` Jamal Hadi Salim
  2013-11-16  1:54         ` David Miller
  2013-11-16  1:53       ` David Miller
  1 sibling, 2 replies; 29+ messages in thread
From: Johannes Berg @ 2013-11-15 13:23 UTC (permalink / raw)
  To: David Miller
  Cc: netdev, linux-wimax, bsingharora, netfilter-devel,
	alex.bluesman.smirnov, dbaryshkov

On Fri, 2013-11-15 at 14:18 +0100, Johannes Berg wrote:

> I've been eyeing the multicast groups as well

Of course, there are also *much* fewer mcast groups, so the saving isn't
nearly as big. But we still have some oddball code to register them all,
basically

	err = register_mc_group();
	if (err)
		goto unregister_family;

(since we have to register the family first, afaict)

sometimes a few of those back to back, and it'd be nicer on the users if
that just went away and was

	family.mcast_groups = my_groups;
	family.n_mcast_groups = ARRAY_SIZE(my_groups);
	family.ops = my_ops;
	family.n_ops = ARRAY_SIZE(my_ops);
	return genl_register_family(&family);

since nobody uses them dynamically anyway, afaict.

johannes


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 0/9] genetlink: reduce ops size and complexity (v2)
  2013-11-15 13:23       ` Johannes Berg
@ 2013-11-15 14:45         ` Jamal Hadi Salim
  2013-11-16  1:54         ` David Miller
  1 sibling, 0 replies; 29+ messages in thread
From: Jamal Hadi Salim @ 2013-11-15 14:45 UTC (permalink / raw)
  To: Johannes Berg, David Miller
  Cc: netdev, linux-wimax, bsingharora, netfilter-devel,
	alex.bluesman.smirnov, dbaryshkov


Are we killing APIs that are already used?
At least that patches that Dave sucked in do. Out of tree
users dont matter?

cheers,
jamal

On 11/15/13 08:23, Johannes Berg wrote:
> On Fri, 2013-11-15 at 14:18 +0100, Johannes Berg wrote:
>
>> I've been eyeing the multicast groups as well
>
> Of course, there are also *much* fewer mcast groups, so the saving isn't
> nearly as big. But we still have some oddball code to register them all,
> basically
>
> 	err = register_mc_group();
> 	if (err)
> 		goto unregister_family;
>
> (since we have to register the family first, afaict)
>
> sometimes a few of those back to back, and it'd be nicer on the users if
> that just went away and was
>
> 	family.mcast_groups = my_groups;
> 	family.n_mcast_groups = ARRAY_SIZE(my_groups);
> 	family.ops = my_ops;
> 	family.n_ops = ARRAY_SIZE(my_ops);
> 	return genl_register_family(&family);
>
> since nobody uses them dynamically anyway, afaict.
>
> johannes
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 0/9] genetlink: reduce ops size and complexity (v2)
  2013-11-15 13:18     ` Johannes Berg
  2013-11-15 13:23       ` Johannes Berg
@ 2013-11-16  1:53       ` David Miller
  2013-11-17  9:12         ` Johannes Berg
  1 sibling, 1 reply; 29+ messages in thread
From: David Miller @ 2013-11-16  1:53 UTC (permalink / raw)
  To: johannes
  Cc: netdev, linux-wimax, bsingharora, netfilter-devel,
	alex.bluesman.smirnov, dbaryshkov

From: Johannes Berg <johannes@sipsolutions.net>
Date: Fri, 15 Nov 2013 14:18:35 +0100

> We could instead register an array of pointers to the groups:
> 
> static const struct mcast_group *my_groups[] = {
> 	&my_foo_mcast_group,
> 	...
> };
> 
> and pass this to the family - that'd still be less space (one pointer
> for each group rather than two in a linked list) and still allow all
> groups and this array to be const, but it's not quite as big a
> saving ...
> 
> Thoughts?

This idea sounds fine.  I don't even thing the array indexing is
odd, especially if we can have named mnenomics for the indices
or similar.

^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 0/9] genetlink: reduce ops size and complexity (v2)
  2013-11-15 13:23       ` Johannes Berg
  2013-11-15 14:45         ` Jamal Hadi Salim
@ 2013-11-16  1:54         ` David Miller
  1 sibling, 0 replies; 29+ messages in thread
From: David Miller @ 2013-11-16  1:54 UTC (permalink / raw)
  To: johannes
  Cc: netdev, linux-wimax, bsingharora, netfilter-devel,
	alex.bluesman.smirnov, dbaryshkov

From: Johannes Berg <johannes@sipsolutions.net>
Date: Fri, 15 Nov 2013 14:23:14 +0100

> On Fri, 2013-11-15 at 14:18 +0100, Johannes Berg wrote:
> 
>> I've been eyeing the multicast groups as well
> 
> Of course, there are also *much* fewer mcast groups, so the saving isn't
> nearly as big. But we still have some oddball code to register them all,
> basically
> 
> 	err = register_mc_group();
> 	if (err)
> 		goto unregister_family;
> 
> (since we have to register the family first, afaict)
> 
> sometimes a few of those back to back, and it'd be nicer on the users if
> that just went away and was
> 
> 	family.mcast_groups = my_groups;
> 	family.n_mcast_groups = ARRAY_SIZE(my_groups);
> 	family.ops = my_ops;
> 	family.n_ops = ARRAY_SIZE(my_ops);
> 	return genl_register_family(&family);
> 
> since nobody uses them dynamically anyway, afaict.

See my other email:

#define genl_register_family_with_ops_mcast(family, ops, groups) \
	__genl_register_family(family, ops, ARRAY_SIZE(ops), groups, ARRAY_SIZE(groups))

you get the idea.


^ permalink raw reply	[flat|nested] 29+ messages in thread

* Re: [PATCH 0/9] genetlink: reduce ops size and complexity (v2)
  2013-11-16  1:53       ` David Miller
@ 2013-11-17  9:12         ` Johannes Berg
  0 siblings, 0 replies; 29+ messages in thread
From: Johannes Berg @ 2013-11-17  9:12 UTC (permalink / raw)
  To: David Miller
  Cc: netdev, linux-wimax, bsingharora, netfilter-devel,
	alex.bluesman.smirnov, dbaryshkov

On Fri, 2013-11-15 at 20:53 -0500, David Miller wrote:

> > We could instead register an array of pointers to the groups:
> > 
> > static const struct mcast_group *my_groups[] = {
> >       &my_foo_mcast_group,
> >       ...
> > };
> > 
> > and pass this to the family - that'd still be less space (one pointer
> > for each group rather than two in a linked list) and still allow all
> > groups and this array to be const, but it's not quite as big a
> > saving ...
> > 
> > Thoughts?
> 
> This idea sounds fine.  I don't even thing the array indexing is
> odd, especially if we can have named mnenomics for the indices
> or similar.

I posted something yesterday, but forgot to reply here - basically as
you'll see in the patches, I decided that we should pass the
family/group array index instead of passing the global group identifier
- this will also prevent new users of the APIs from abusing them like
quota/dropmonitor unfortunately did.

johannes

^ permalink raw reply	[flat|nested] 29+ messages in thread

end of thread, other threads:[~2013-11-17  9:12 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-11-14  9:14 [RFC 0/7] genetlink: reduce ops size and complexity Johannes Berg
2013-11-14  9:14 ` [RFC 1/7] taskstats: use genl_register_family_with_ops() Johannes Berg
2013-11-14  9:14 ` [RFC 2/7] hsr: " Johannes Berg
2013-11-14  9:14 ` [RFC 3/7] ieee802154: " Johannes Berg
2013-11-14  9:14 ` [RFC 4/7] wimax: " Johannes Berg
2013-11-14  9:14 ` [RFC 5/7] genetlink: remove genl_register_ops/genl_unregister_ops Johannes Berg
2013-11-14  9:14 ` [RFC 6/7] genetlink: register family ops as array Johannes Berg
2013-11-14  9:14 ` [RFC 7/7] genetlink: allow making ops const Johannes Berg
2013-11-14 13:41 ` [RFC 8/7] genetlink: make all genl_ops users const Johannes Berg
2013-11-14 14:01 ` [RFC 9/7] genetlink: make genl_ops flags a u8 and move to end Johannes Berg
2013-11-14 14:36 ` [RFC 0/7] genetlink: reduce ops size and complexity Johannes Berg
2013-11-14 16:02 ` Johannes Berg
2013-11-14 16:14 ` [PATCH 0/9] genetlink: reduce ops size and complexity (v2) Johannes Berg
2013-11-14 16:14   ` [PATCH 1/9] taskstats: use genl_register_family_with_ops() Johannes Berg
2013-11-14 16:14   ` [PATCH 2/9] hsr: " Johannes Berg
2013-11-14 16:14   ` [PATCH 3/9] ieee802154: " Johannes Berg
2013-11-14 16:14   ` [PATCH 4/9] wimax: " Johannes Berg
2013-11-14 16:14   ` [PATCH 5/9] genetlink: remove genl_register_ops/genl_unregister_ops Johannes Berg
2013-11-14 16:14   ` [PATCH 6/9] genetlink: register family ops as array Johannes Berg
2013-11-14 16:14   ` [PATCH 7/9] genetlink: allow making ops const Johannes Berg
2013-11-14 16:14   ` [PATCH 8/9] genetlink: make all genl_ops users const Johannes Berg
2013-11-14 16:14   ` [PATCH 9/9] genetlink: make genl_ops flags a u8 and move to end Johannes Berg
2013-11-14 22:12   ` [PATCH 0/9] genetlink: reduce ops size and complexity (v2) David Miller
2013-11-15 13:18     ` Johannes Berg
2013-11-15 13:23       ` Johannes Berg
2013-11-15 14:45         ` Jamal Hadi Salim
2013-11-16  1:54         ` David Miller
2013-11-16  1:53       ` David Miller
2013-11-17  9:12         ` Johannes Berg

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.