All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jakub Kicinski <kuba@kernel.org>
To: davem@davemloft.net
Cc: netdev@vger.kernel.org, edumazet@google.com, pabeni@redhat.com,
	andrew+netdev@lunn.ch, horms@kernel.org, geert@linux-m68k.org,
	chleroy@kernel.org, npiggin@gmail.com, mpe@ellerman.id.au,
	maddy@linux.ibm.com, linux-mips@vger.kernel.org,
	linux-m68k@lists.linux-m68k.org, linuxppc-dev@lists.ozlabs.org,
	Jakub Kicinski <kuba@kernel.org>
Subject: [PATCH net-next 1/2] appletalk: stop storing per-interface state in struct net_device
Date: Mon, 15 Jun 2026 15:29:34 -0700	[thread overview]
Message-ID: <20260615222935.947233-2-kuba@kernel.org> (raw)
In-Reply-To: <20260615222935.947233-1-kuba@kernel.org>

AppleTalk keeps its per-interface control block (struct atalk_iface)
directly in struct netdevice (dev->atalk_ptr). This is the only thing
tying the protocol into the core net_device layout and is the sole
blocker to moving AppleTalk out of tree.

Replace dev->atalk_ptr with a small ifindex-keyed hashtable internal
to ddp.c. The existing atalk_interfaces list stays the owner of the iface
objects; the hashtable is purely a fast dev->iface index and reuses
the same atalk_interfaces_lock.

AFAICT this patch does not make this code any more racy than it already
is, I'm sure Sashiko will point out some basically existing bugs.
AFAICT atalk_interfaces_lock is the innermost lock already.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
---
 .../networking/net_cachelines/net_device.rst  |  1 -
 include/linux/atalk.h                         |  8 +---
 include/linux/netdevice.h                     |  4 --
 net/appletalk/ddp.c                           | 48 +++++++++++++++++--
 4 files changed, 45 insertions(+), 16 deletions(-)

diff --git a/Documentation/networking/net_cachelines/net_device.rst b/Documentation/networking/net_cachelines/net_device.rst
index eb2e6851c6f6..512f6d6fa3d8 100644
--- a/Documentation/networking/net_cachelines/net_device.rst
+++ b/Documentation/networking/net_cachelines/net_device.rst
@@ -90,7 +90,6 @@ struct inet6_dev*                   ip6_ptr                     read_mostly
 struct vlan_info*                   vlan_info
 struct dsa_port*                    dsa_ptr
 struct tipc_bearer*                 tipc_ptr
-void*                               atalk_ptr
 struct wireless_dev*                ieee80211_ptr
 struct wpan_dev*                    ieee802154_ptr
 struct mpls_dev*                    mpls_ptr
diff --git a/include/linux/atalk.h b/include/linux/atalk.h
index a55bfc6567d0..ce7e6bfa9e2a 100644
--- a/include/linux/atalk.h
+++ b/include/linux/atalk.h
@@ -30,6 +30,7 @@ struct atalk_iface {
 #define ATIF_PROBE_FAIL	2		/* Probe collided */
 	struct atalk_netrange	nets;
 	struct atalk_iface	*next;
+	struct hlist_node	hash_node;	/* keyed on dev->ifindex */
 };
 	
 struct atalk_sock {
@@ -113,12 +114,7 @@ extern int aarp_proto_init(void);
 /* Inter module exports */
 
 /* Give a device find its atif control structure */
-#if IS_ENABLED(CONFIG_ATALK)
-static inline struct atalk_iface *atalk_find_dev(struct net_device *dev)
-{
-	return dev->atalk_ptr;
-}
-#endif
+extern struct atalk_iface *atalk_find_dev(struct net_device *dev);
 
 extern struct atalk_addr *atalk_find_dev_addr(struct net_device *dev);
 extern struct net_device *atrtr_get_dev(struct atalk_addr *sa);
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 7f4f0837c09f..655564621f28 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -1947,7 +1947,6 @@ enum netdev_reg_state {
  *	@vlan_info:	VLAN info
  *	@dsa_ptr:	dsa specific data
  *	@tipc_ptr:	TIPC specific data
- *	@atalk_ptr:	AppleTalk link
  *	@ip_ptr:	IPv4 specific data
  *	@ip6_ptr:	IPv6 specific data
  *	@ieee80211_ptr:	IEEE 802.11 specific data, assign before registering
@@ -2349,9 +2348,6 @@ struct net_device {
 #if IS_ENABLED(CONFIG_TIPC)
 	struct tipc_bearer __rcu *tipc_ptr;
 #endif
-#if IS_ENABLED(CONFIG_ATALK)
-	void 			*atalk_ptr;
-#endif
 #if IS_ENABLED(CONFIG_CFG80211)
 	struct wireless_dev	*ieee80211_ptr;
 #endif
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
index 30a6dc06291c..afb86ce6e644 100644
--- a/net/appletalk/ddp.c
+++ b/net/appletalk/ddp.c
@@ -52,6 +52,7 @@
 #include <linux/termios.h>	/* For TIOCOUTQ/INQ */
 #include <linux/compat.h>
 #include <linux/slab.h>
+#include <linux/hashtable.h>
 #include <net/datalink.h>
 #include <net/psnap.h>
 #include <net/sock.h>
@@ -204,6 +205,33 @@ DEFINE_RWLOCK(atalk_routes_lock);
 struct atalk_iface *atalk_interfaces;
 DEFINE_RWLOCK(atalk_interfaces_lock);
 
+/* Fast dev->iface lookup, keyed on ifindex. Shares atalk_interfaces_lock with
+ * the atalk_interfaces list, which remains the owner of the iface objects.
+ */
+#define ATALK_IFACE_HASH_BITS	8
+static DEFINE_HASHTABLE(atalk_iface_hash, ATALK_IFACE_HASH_BITS);
+
+/* Find the iface for @dev. Caller must hold atalk_interfaces_lock. */
+static struct atalk_iface *__atalk_find_dev(struct net_device *dev)
+{
+	struct atalk_iface *iface;
+
+	hash_for_each_possible(atalk_iface_hash, iface, hash_node, dev->ifindex)
+		if (iface->dev == dev)
+			return iface;
+	return NULL;
+}
+
+struct atalk_iface *atalk_find_dev(struct net_device *dev)
+{
+	struct atalk_iface *iface;
+
+	read_lock_bh(&atalk_interfaces_lock);
+	iface = __atalk_find_dev(dev);
+	read_unlock_bh(&atalk_interfaces_lock);
+	return iface;
+}
+
 /* For probing devices or in a routerless network */
 struct atalk_route atrtr_default;
 
@@ -221,9 +249,9 @@ static void atif_drop_device(struct net_device *dev)
 	while ((tmp = *iface) != NULL) {
 		if (tmp->dev == dev) {
 			*iface = tmp->next;
+			hash_del(&tmp->hash_node);
 			dev_put(dev);
 			kfree(tmp);
-			dev->atalk_ptr = NULL;
 		} else
 			iface = &tmp->next;
 	}
@@ -240,13 +268,13 @@ static struct atalk_iface *atif_add_device(struct net_device *dev,
 
 	dev_hold(dev);
 	iface->dev = dev;
-	dev->atalk_ptr = iface;
 	iface->address = *sa;
 	iface->status = 0;
 
 	write_lock_bh(&atalk_interfaces_lock);
 	iface->next = atalk_interfaces;
 	atalk_interfaces = iface;
+	hash_add(atalk_iface_hash, &iface->hash_node, dev->ifindex);
 	write_unlock_bh(&atalk_interfaces_lock);
 out:
 	return iface;
@@ -347,8 +375,15 @@ static int atif_proxy_probe_device(struct atalk_iface *atif,
 
 struct atalk_addr *atalk_find_dev_addr(struct net_device *dev)
 {
-	struct atalk_iface *iface = dev->atalk_ptr;
-	return iface ? &iface->address : NULL;
+	struct atalk_addr *addr = NULL;
+	struct atalk_iface *iface;
+
+	read_lock_bh(&atalk_interfaces_lock);
+	iface = __atalk_find_dev(dev);
+	if (iface)
+		addr = &iface->address;
+	read_unlock_bh(&atalk_interfaces_lock);
+	return addr;
 }
 
 static struct atalk_addr *atalk_find_primary(void)
@@ -388,8 +423,10 @@ static struct atalk_addr *atalk_find_primary(void)
  */
 static struct atalk_iface *atalk_find_anynet(int node, struct net_device *dev)
 {
-	struct atalk_iface *iface = dev->atalk_ptr;
+	struct atalk_iface *iface;
 
+	read_lock_bh(&atalk_interfaces_lock);
+	iface = __atalk_find_dev(dev);
 	if (!iface || iface->status & ATIF_PROBE)
 		goto out_err;
 
@@ -398,6 +435,7 @@ static struct atalk_iface *atalk_find_anynet(int node, struct net_device *dev)
 	    node != ATADDR_ANYNODE)
 		goto out_err;
 out:
+	read_unlock_bh(&atalk_interfaces_lock);
 	return iface;
 out_err:
 	iface = NULL;
-- 
2.54.0


  reply	other threads:[~2026-06-15 22:29 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-15 22:29 [PATCH net-next 0/2] appletalk: move the protocol out of tree Jakub Kicinski
2026-06-15 22:29 ` Jakub Kicinski [this message]
2026-06-15 22:29 ` [PATCH net-next 2/2] " Jakub Kicinski
2026-06-15 23:34 ` [PATCH net-next 0/2] " John Paul Adrian Glaubitz
2026-06-16  0:55   ` Jakub Kicinski
2026-06-16  2:01 ` Stephen Hemminger

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260615222935.947233-2-kuba@kernel.org \
    --to=kuba@kernel.org \
    --cc=andrew+netdev@lunn.ch \
    --cc=chleroy@kernel.org \
    --cc=davem@davemloft.net \
    --cc=edumazet@google.com \
    --cc=geert@linux-m68k.org \
    --cc=horms@kernel.org \
    --cc=linux-m68k@lists.linux-m68k.org \
    --cc=linux-mips@vger.kernel.org \
    --cc=linuxppc-dev@lists.ozlabs.org \
    --cc=maddy@linux.ibm.com \
    --cc=mpe@ellerman.id.au \
    --cc=netdev@vger.kernel.org \
    --cc=npiggin@gmail.com \
    --cc=pabeni@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.