svn commit: r236052 - stable/9/sys/net
Andrew Thompson
thompsa at FreeBSD.org
Sat May 26 07:43:17 UTC 2012
Author: thompsa
Date: Sat May 26 07:43:17 2012
New Revision: 236052
URL: http://svn.freebsd.org/changeset/base/236052
Log:
MFC r234488
Move the interface media check to a taskqueue, some interfaces (usb) sleep
during SIOCGIFMEDIA and we were holding locks.
Modified:
stable/9/sys/net/bridgestp.c
stable/9/sys/net/bridgestp.h
Directory Properties:
stable/9/sys/ (props changed)
stable/9/sys/amd64/include/xen/ (props changed)
stable/9/sys/boot/ (props changed)
stable/9/sys/boot/i386/efi/ (props changed)
stable/9/sys/boot/ia64/efi/ (props changed)
stable/9/sys/boot/ia64/ski/ (props changed)
stable/9/sys/boot/powerpc/boot1.chrp/ (props changed)
stable/9/sys/boot/powerpc/ofw/ (props changed)
stable/9/sys/cddl/contrib/opensolaris/ (props changed)
stable/9/sys/conf/ (props changed)
stable/9/sys/contrib/dev/acpica/ (props changed)
stable/9/sys/contrib/octeon-sdk/ (props changed)
stable/9/sys/contrib/pf/ (props changed)
stable/9/sys/contrib/x86emu/ (props changed)
stable/9/sys/dev/ (props changed)
stable/9/sys/dev/e1000/ (props changed)
stable/9/sys/dev/ixgbe/ (props changed)
stable/9/sys/fs/ (props changed)
stable/9/sys/fs/ntfs/ (props changed)
stable/9/sys/modules/ (props changed)
Modified: stable/9/sys/net/bridgestp.c
==============================================================================
--- stable/9/sys/net/bridgestp.c Sat May 26 07:42:32 2012 (r236051)
+++ stable/9/sys/net/bridgestp.c Sat May 26 07:43:17 2012 (r236052)
@@ -127,7 +127,7 @@ static int bstp_rerooted(struct bstp_sta
static uint32_t bstp_calc_path_cost(struct bstp_port *);
static void bstp_notify_state(void *, int);
static void bstp_notify_rtage(void *, int);
-static void bstp_ifupdstatus(struct bstp_state *, struct bstp_port *);
+static void bstp_ifupdstatus(void *, int);
static void bstp_enable_port(struct bstp_state *, struct bstp_port *);
static void bstp_disable_port(struct bstp_state *, struct bstp_port *);
static void bstp_tick(void *);
@@ -1677,7 +1677,7 @@ bstp_set_autoptp(struct bstp_port *bp, i
if (set) {
bp->bp_flags |= BSTP_PORT_AUTOPTP;
if (bp->bp_role != BSTP_ROLE_DISABLED)
- bstp_ifupdstatus(bs, bp);
+ taskqueue_enqueue(taskqueue_swi, &bp->bp_mediatask);
} else
bp->bp_flags &= ~BSTP_PORT_AUTOPTP;
BSTP_UNLOCK(bs);
@@ -1771,69 +1771,89 @@ bstp_linkstate(struct bstp_port *bp)
{
struct bstp_state *bs = bp->bp_bs;
+ if (!bp->bp_active)
+ return;
+
+ bstp_ifupdstatus(bp, 0);
BSTP_LOCK(bs);
- if (bp->bp_active) {
- bstp_ifupdstatus(bs, bp);
- bstp_update_state(bs, bp);
- }
+ bstp_update_state(bs, bp);
BSTP_UNLOCK(bs);
}
static void
-bstp_ifupdstatus(struct bstp_state *bs, struct bstp_port *bp)
+bstp_ifupdstatus(void *arg, int pending)
{
+ struct bstp_port *bp = (struct bstp_port *)arg;
+ struct bstp_state *bs = bp->bp_bs;
struct ifnet *ifp = bp->bp_ifp;
struct ifmediareq ifmr;
- int error = 0;
+ int error, changed;
- BSTP_LOCK_ASSERT(bs);
+ if (!bp->bp_active)
+ return;
bzero((char *)&ifmr, sizeof(ifmr));
error = (*ifp->if_ioctl)(ifp, SIOCGIFMEDIA, (caddr_t)&ifmr);
+ BSTP_LOCK(bs);
+ changed = 0;
if ((error == 0) && (ifp->if_flags & IFF_UP)) {
if (ifmr.ifm_status & IFM_ACTIVE) {
/* A full-duplex link is assumed to be point to point */
if (bp->bp_flags & BSTP_PORT_AUTOPTP) {
- bp->bp_ptp_link =
- ifmr.ifm_active & IFM_FDX ? 1 : 0;
+ int fdx;
+
+ fdx = ifmr.ifm_active & IFM_FDX ? 1 : 0;
+ if (bp->bp_ptp_link ^ fdx) {
+ bp->bp_ptp_link = fdx;
+ changed = 1;
+ }
}
/* Calc the cost if the link was down previously */
if (bp->bp_flags & BSTP_PORT_PNDCOST) {
- bp->bp_path_cost = bstp_calc_path_cost(bp);
+ uint32_t cost;
+
+ cost = bstp_calc_path_cost(bp);
+ if (bp->bp_path_cost != cost) {
+ bp->bp_path_cost = cost;
+ changed = 1;
+ }
bp->bp_flags &= ~BSTP_PORT_PNDCOST;
}
- if (bp->bp_role == BSTP_ROLE_DISABLED)
+ if (bp->bp_role == BSTP_ROLE_DISABLED) {
bstp_enable_port(bs, bp);
+ changed = 1;
+ }
} else {
if (bp->bp_role != BSTP_ROLE_DISABLED) {
bstp_disable_port(bs, bp);
+ changed = 1;
if ((bp->bp_flags & BSTP_PORT_ADMEDGE) &&
bp->bp_protover == BSTP_PROTO_RSTP)
bp->bp_operedge = 1;
}
}
- return;
- }
-
- if (bp->bp_infois != BSTP_INFO_DISABLED)
+ } else if (bp->bp_infois != BSTP_INFO_DISABLED) {
bstp_disable_port(bs, bp);
+ changed = 1;
+ }
+ if (changed)
+ bstp_assign_roles(bs);
+ BSTP_UNLOCK(bs);
}
static void
bstp_enable_port(struct bstp_state *bs, struct bstp_port *bp)
{
bp->bp_infois = BSTP_INFO_AGED;
- bstp_assign_roles(bs);
}
static void
bstp_disable_port(struct bstp_state *bs, struct bstp_port *bp)
{
bp->bp_infois = BSTP_INFO_DISABLED;
- bstp_assign_roles(bs);
}
static void
@@ -1853,7 +1873,7 @@ bstp_tick(void *arg)
if (bstp_timer_dectest(&bs->bs_link_timer)) {
LIST_FOREACH(bp, &bs->bs_bplist, bp_next) {
if (!(bp->bp_ifp->if_capabilities & IFCAP_LINKSTATE))
- bstp_ifupdstatus(bs, bp);
+ taskqueue_enqueue(taskqueue_swi, &bp->bp_mediatask);
}
bstp_timer_start(&bs->bs_link_timer, BSTP_LINK_TIMER);
}
@@ -2063,7 +2083,7 @@ bstp_reinit(struct bstp_state *bs)
LIST_FOREACH(bp, &bs->bs_bplist, bp_next) {
bp->bp_port_id = (bp->bp_priority << 8) |
(bp->bp_ifp->if_index & 0xfff);
- bstp_ifupdstatus(bs, bp);
+ taskqueue_enqueue(taskqueue_swi, &bp->bp_mediatask);
}
bstp_assign_roles(bs);
@@ -2184,6 +2204,7 @@ bstp_create(struct bstp_state *bs, struc
bp->bp_priority = BSTP_DEFAULT_PORT_PRIORITY;
TASK_INIT(&bp->bp_statetask, 0, bstp_notify_state, bp);
TASK_INIT(&bp->bp_rtagetask, 0, bstp_notify_rtage, bp);
+ TASK_INIT(&bp->bp_mediatask, 0, bstp_ifupdstatus, bp);
/* Init state */
bp->bp_infois = BSTP_INFO_DISABLED;
@@ -2247,4 +2268,5 @@ bstp_destroy(struct bstp_port *bp)
KASSERT(bp->bp_active == 0, ("port is still attached"));
taskqueue_drain(taskqueue_swi, &bp->bp_statetask);
taskqueue_drain(taskqueue_swi, &bp->bp_rtagetask);
+ taskqueue_drain(taskqueue_swi, &bp->bp_mediatask);
}
Modified: stable/9/sys/net/bridgestp.h
==============================================================================
--- stable/9/sys/net/bridgestp.h Sat May 26 07:42:32 2012 (r236051)
+++ stable/9/sys/net/bridgestp.h Sat May 26 07:43:17 2012 (r236052)
@@ -326,6 +326,7 @@ struct bstp_port {
uint8_t bp_txcount;
struct task bp_statetask;
struct task bp_rtagetask;
+ struct task bp_mediatask;
};
/*
More information about the svn-src-stable-9
mailing list