batman-adv: compat: Substitute compat code for netlink constification

Message ID 20161018232239.GI6366@otheros (mailing list archive)
State RFC, archived
Headers

Commit Message

Linus Lüssing Oct. 18, 2016, 11:22 p.m. UTC
  On Tue, Oct 18, 2016 at 11:28:23PM +0200, Sven Eckelmann wrote:
> Doesn't seem to scale. Especially when we think about batadv_netlink_ops
> which should also be const. It is currently not const because of the
> Linux <= 3.13 workaround.

Hm, okay, batadv_netlink_ops is a little more tricky/larger, yes.
What about a memcpy'ing approach with BUILD_BUG_ON()'s as
safe-guards like this:
  

Comments

Sven Eckelmann Oct. 19, 2016, 6:31 a.m. UTC | #1
On Mittwoch, 19. Oktober 2016 01:22:39 CEST Linus Lüssing wrote:
> On Tue, Oct 18, 2016 at 11:28:23PM +0200, Sven Eckelmann wrote:
> > Doesn't seem to scale. Especially when we think about batadv_netlink_ops
> > which should also be const. It is currently not const because of the
> > Linux <= 3.13 workaround.
> 
> Hm, okay, batadv_netlink_ops is a little more tricky/larger, yes.
> What about a memcpy'ing approach with BUILD_BUG_ON()'s as
> safe-guards like this:

Yes, this would also be an idea. But I would personally just use the 
coccinelle approach because it needs less extra hacks. Or do you have any 
problems with coccinelle? My personal preferences are (at the moment):

1. code which doesn't need compat code
2. code which can supported with clean (not too hacky) compat-include
3. code which can be supported with coccinelle
4. code which can be supported with compat.h hacks
5. code which can be supported with small patches

The replace.sh was just a quick way to make sure we can ship 2016.4 without to 
many extra modifications.

Btw. this is right now only something for later. It is more important to get 
your other changes in master. And also to get the patchwork queue smaller - so 
reviews are more than welcome.

Kind regards,
	Sven
  
Linus Lüssing Oct. 20, 2016, 6:33 p.m. UTC | #2
On Wed, Oct 19, 2016 at 08:31:03AM +0200, Sven Eckelmann wrote:
> On Mittwoch, 19. Oktober 2016 01:22:39 CEST Linus Lüssing wrote:
> > On Tue, Oct 18, 2016 at 11:28:23PM +0200, Sven Eckelmann wrote:
> > > Doesn't seem to scale. Especially when we think about batadv_netlink_ops
> > > which should also be const. It is currently not const because of the
> > > Linux <= 3.13 workaround.
> > 
> > Hm, okay, batadv_netlink_ops is a little more tricky/larger, yes.
> > What about a memcpy'ing approach with BUILD_BUG_ON()'s as
> > safe-guards like this:
> 
> Yes, this would also be an idea. But I would personally just use the 
> coccinelle approach because it needs less extra hacks. Or do you have any 
> problems with coccinelle?

Hm, no, dunno. Just haven't really looked at coccinelle yet and
thought your point 3. (cocinelle) were on place 4. instead.
Besides, I had fun creating this compat patch and was marvelled
that the BUILD_BUG_ON() worked even with function parameters :D
(maybe, actually because they were const now? You clever compiler
:D).

Also, it looks like the whole compat infrastructure is growing and
I'm wondering whether it is easier to maintain slightly larger
compat-includes vs. then two more places where compat changes
could come from.


But I don't feel strongly about it, if others think coccinelle is
easier to review and maintain, then I'm fine with it and will have
a closer look at coccinelle :).
  

Patch

diff --git a/compat-include/net/genetlink.h b/compat-include/net/genetlink.h
index 72a8991..f16bf35 100644
--- a/compat-include/net/genetlink.h
+++ b/compat-include/net/genetlink.h
@@ -28,6 +28,9 @@ 
 
 #include <linux/export.h>
 
+static struct genl_ops __batadv_netlink_ops[12];
+static struct genl_multicast_group __batadv_netlink_mcgrps[1];
+
 struct batadv_genl_family {
 	/* data handled by the actual kernel */
 	struct genl_family family;
@@ -137,15 +140,23 @@  static inline int batadv_genl_register_family(struct genl_family *family)
 	return ret;
 }
 
-static inline int
+static inline int __init
 batadv_genl_register_family_with_ops_grps(struct genl_family *family,
-					  struct genl_ops *ops, size_t n_ops,
-					  struct genl_multicast_group *mcgrps,
+					  const struct genl_ops *ops, size_t n_ops,
+					  const struct genl_multicast_group *mcgrps,
 					  size_t n_mcgrps)
 {
-	family->ops = ops;
+	BUILD_BUG_ON(ARRAY_SIZE(__batadv_netlink_ops) != n_ops);
+	BUILD_BUG_ON(ARRAY_SIZE(__batadv_netlink_mcgrps) != n_mcgrps);
+	BUILD_BUG_ON(sizeof(__batadv_netlink_ops) != sizeof(*ops) * n_ops);
+	BUILD_BUG_ON(sizeof(__batadv_netlink_mcgrps) != sizeof(*mcgrps) * n_mcgrps);
+
+	memcpy(__batadv_netlink_ops, ops, sizeof(__batadv_netlink_ops));
+	memcpy(__batadv_netlink_mcgrps, mcgrps, sizeof(__batadv_netlink_mcgrps));
+
+	family->ops = __batadv_netlink_ops;
 	family->n_ops = n_ops;
-	family->mcgrps = mcgrps;
+	family->mcgrps = __batadv_netlink_mcgrps;
 	family->n_mcgrps = n_mcgrps;
 	family->module = THIS_MODULE;
 
diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c
index 64cb6ac..aee20a3 100644
--- a/net/batman-adv/netlink.c
+++ b/net/batman-adv/netlink.c
@@ -534,7 +534,7 @@  batadv_netlink_dump_hardifs(struct sk_buff *msg, struct netlink_callback *cb)
 	return msg->len;
 }
 
-static struct genl_ops batadv_netlink_ops[] = {
+static const struct genl_ops batadv_netlink_ops[] = {
 	{
 		.cmd = BATADV_CMD_GET_MESH_INFO,
 		.flags = GENL_ADMIN_PERM,