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
next prev parent 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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox