Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/net/lagg Fix to call lacp_linkstate with IFNET_LOCK held
details: https://anonhg.NetBSD.org/src/rev/dfa29ee42ab5
branches: trunk
changeset: 359594:dfa29ee42ab5
user: yamaguchi <yamaguchi%NetBSD.org@localhost>
date: Wed Jan 12 08:23:53 2022 +0000
description:
Fix to call lacp_linkstate with IFNET_LOCK held
Network stack calls lacp_linkstate through lagg_port_ioctl when
doing "ifconfig up" or "ifconfig down" to an interface that is
a member of lagg(4). And IFNET_LOCK in the member interface
is held while the ioctl.
Therefore, lacp_linkstate is renamed to
lacp_linkstate_ifnet_locked, and always called with IFNET_LOCK
held. It avoids locking agains myself.
diffstat:
sys/net/lagg/if_lagg.c | 13 ++++++++++---
sys/net/lagg/if_lagg_lacp.c | 28 +++++++++++++++++++---------
sys/net/lagg/if_laggproto.h | 6 +++---
3 files changed, 32 insertions(+), 15 deletions(-)
diffs (179 lines):
diff -r 2dfa450efd77 -r dfa29ee42ab5 sys/net/lagg/if_lagg.c
--- a/sys/net/lagg/if_lagg.c Wed Jan 12 01:21:36 2022 +0000
+++ b/sys/net/lagg/if_lagg.c Wed Jan 12 08:23:53 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_lagg.c,v 1.29 2022/01/12 01:21:36 riastradh Exp $ */
+/* $NetBSD: if_lagg.c,v 1.30 2022/01/12 08:23:53 yamaguchi Exp $ */
/*
* Copyright (c) 2005, 2006 Reyk Floeter <reyk%openbsd.org@localhost>
@@ -20,7 +20,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_lagg.c,v 1.29 2022/01/12 01:21:36 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_lagg.c,v 1.30 2022/01/12 08:23:53 yamaguchi Exp $");
#ifdef _KERNEL_OPT
#include "opt_inet.h"
@@ -102,7 +102,7 @@
.pr_stopport = lacp_stopport,
.pr_protostat = lacp_protostat,
.pr_portstat = lacp_portstat,
- .pr_linkstate = lacp_linkstate,
+ .pr_linkstate = lacp_linkstate_ifnet_locked,
.pr_ioctl = lacp_ioctl,
},
[LAGG_PROTO_FAILOVER] = {
@@ -1490,6 +1490,8 @@
lagg_proto pr;
int bound;
+ KASSERT(IFNET_LOCKED(lp->lp_ifp));
+
bound = curlwp_bind();
var = lagg_variant_getref(sc, &psref);
@@ -2692,6 +2694,8 @@
goto fallback;
}
+ KASSERT(IFNET_LOCKED(lp->lp_ifp));
+
switch (cmd) {
case SIOCSIFCAP:
case SIOCSIFMTU:
@@ -2817,7 +2821,10 @@
}
pserialize_read_exit(s);
+ IFNET_LOCK(lp->lp_ifp);
lagg_proto_linkstate(lp->lp_softc, lp);
+ IFNET_UNLOCK(lp->lp_ifp);
+
lagg_port_putref(lp, &psref);
curlwp_bindx(bound);
}
diff -r 2dfa450efd77 -r dfa29ee42ab5 sys/net/lagg/if_lagg_lacp.c
--- a/sys/net/lagg/if_lagg_lacp.c Wed Jan 12 01:21:36 2022 +0000
+++ b/sys/net/lagg/if_lagg_lacp.c Wed Jan 12 08:23:53 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_lagg_lacp.c,v 1.11 2022/01/06 12:09:42 riastradh Exp $ */
+/* $NetBSD: if_lagg_lacp.c,v 1.12 2022/01/12 08:23:53 yamaguchi Exp $ */
/*-
* SPDX-License-Identifier: BSD-2-Clause-NetBSD
@@ -31,7 +31,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_lagg_lacp.c,v 1.11 2022/01/06 12:09:42 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_lagg_lacp.c,v 1.12 2022/01/12 08:23:53 yamaguchi Exp $");
#ifdef _KERNEL_OPT
#include "opt_lagg.h"
@@ -212,8 +212,6 @@
#define LACP_LOCK(_sc) mutex_enter(&(_sc)->lsc_lock)
#define LACP_UNLOCK(_sc) mutex_exit(&(_sc)->lsc_lock)
#define LACP_LOCKED(_sc) mutex_owned(&(_sc)->lsc_lock)
-#define LACP_LINKSTATE(_sc, _lp) \
- lacp_linkstate((struct lagg_proto_softc *)(_sc), (_lp))
#define LACP_TIMER_ARM(_lacpp, _timer, _val) \
(_lacpp)->lp_timer[(_timer)] = (_val)
#define LACP_TIMER_DISARM(_lacpp, _timer) \
@@ -242,6 +240,7 @@
static void lacp_tick(void *);
static void lacp_tick_work(struct lagg_work *, void *);
+static void lacp_linkstate(struct lagg_proto_softc *, struct lagg_port *);
static uint32_t lacp_ifmedia2lacpmedia(u_int);
static void lacp_port_disable(struct lacp_softc *, struct lacp_port *);
static void lacp_port_enable(struct lacp_softc *, struct lacp_port *);
@@ -673,7 +672,7 @@
lp->lp_proto_ctx = (void *)lacpp;
lp->lp_prio = ntohs(lacpp->lp_actor.lpi_portprio);
- LACP_LINKSTATE(lsc, lp);
+ lacp_linkstate(xlsc, lp);
return 0;
}
@@ -689,7 +688,7 @@
prio = (uint16_t)MIN(lp->lp_prio, UINT16_MAX);
lacpp->lp_actor.lpi_portprio = htons(prio);
- LACP_LINKSTATE((struct lacp_softc *)xlsc, lp);
+ lacp_linkstate(xlsc, lp);
}
void
@@ -821,7 +820,7 @@
}
void
-lacp_linkstate(struct lagg_proto_softc *xlsc, struct lagg_port *lp)
+lacp_linkstate_ifnet_locked(struct lagg_proto_softc *xlsc, struct lagg_port *lp)
{
struct lacp_softc *lsc;
struct lacp_port *lacpp;
@@ -831,6 +830,8 @@
uint32_t media, old_media;
int error;
+ KASSERT(IFNET_LOCKED(lp->lp_ifp));
+
lsc = (struct lacp_softc *)xlsc;
ifp_port = lp->lp_ifp;
@@ -839,9 +840,7 @@
memset(&ifmr, 0, sizeof(ifmr));
ifmr.ifm_count = 0;
- IFNET_LOCK(ifp_port);
error = if_ioctl(ifp_port, SIOCGIFMEDIA, (void *)&ifmr);
- IFNET_UNLOCK(ifp_port);
if (error == 0) {
media = lacp_ifmedia2lacpmedia(ifmr.ifm_active);
} else if (error != ENOTTY){
@@ -2644,3 +2643,14 @@
return rv;
}
+
+static void
+lacp_linkstate(struct lagg_proto_softc *xlsc, struct lagg_port *lp)
+{
+
+ IFNET_ASSERT_UNLOCKED(lp->lp_ifp);
+
+ IFNET_LOCK(lp->lp_ifp);
+ lacp_linkstate_ifnet_locked(xlsc, lp);
+ IFNET_UNLOCK(lp->lp_ifp);
+}
diff -r 2dfa450efd77 -r dfa29ee42ab5 sys/net/lagg/if_laggproto.h
--- a/sys/net/lagg/if_laggproto.h Wed Jan 12 01:21:36 2022 +0000
+++ b/sys/net/lagg/if_laggproto.h Wed Jan 12 08:23:53 2022 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: if_laggproto.h,v 1.9 2021/10/19 07:52:33 yamaguchi Exp $ */
+/* $NetBSD: if_laggproto.h,v 1.10 2022/01/12 08:23:53 yamaguchi Exp $ */
/*
* Copyright (c) 2021 Internet Initiative Japan Inc.
@@ -199,8 +199,8 @@
* - IFNET_LOCK(sc_if) -> LAGG_LOCK -> ETHER_LOCK(sc_if) -> a lock in
* struct lagg_port_softc
* - IFNET_LOCK(sc_if) -> LAGG_LOCK -> IFNET_LOCK(lp_ifp)
+ * - IFNET_LOCK(lp_ifp) -> a lock in struct lagg_proto_softc
* - Currently, there is no combination of following locks
- * - IFNET_LOCK(lp_ifp) and a lock in struct lagg_proto_softc
* - IFNET_LOCK(lp_ifp) and ETHER_LOCK(sc_if)
*/
#define LAGG_LOCK(_sc) mutex_enter(&(_sc)->sc_lock)
@@ -320,6 +320,6 @@
struct laggreqproto *);
void lacp_portstat(struct lagg_proto_softc *, struct lagg_port *,
struct laggreqport *);
-void lacp_linkstate(struct lagg_proto_softc *, struct lagg_port *);
+void lacp_linkstate_ifnet_locked(struct lagg_proto_softc *, struct lagg_port *);
int lacp_ioctl(struct lagg_proto_softc *, struct laggreqproto *);
#endif
Home |
Main Index |
Thread Index |
Old Index