svn commit: r280533 - stable/10/sys/dev/sfxge
Andrew Rybchenko
arybchik at FreeBSD.org
Wed Mar 25 10:38:23 UTC 2015
Author: arybchik
Date: Wed Mar 25 10:38:22 2015
New Revision: 280533
URL: https://svnweb.freebsd.org/changeset/base/280533
Log:
MFC: 278838
sfxge: SYSCTL_IN/OUT should not be called with non-sleepable lock held
The problem is found using WITNESS option enabled.
Sponsored by: Solarflare Communications, Inc.
Approved by: gnn (mentor)
Modified:
stable/10/sys/dev/sfxge/sfxge_port.c
Directory Properties:
stable/10/ (props changed)
Modified: stable/10/sys/dev/sfxge/sfxge_port.c
==============================================================================
--- stable/10/sys/dev/sfxge/sfxge_port.c Wed Mar 25 10:37:36 2015 (r280532)
+++ stable/10/sys/dev/sfxge/sfxge_port.c Wed Mar 25 10:38:22 2015 (r280533)
@@ -91,16 +91,15 @@ sfxge_mac_stat_handler(SYSCTL_HANDLER_AR
struct sfxge_softc *sc = arg1;
unsigned int id = arg2;
int rc;
+ uint64_t val;
SFXGE_PORT_LOCK(&sc->port);
- if ((rc = sfxge_mac_stat_update(sc)) != 0)
- goto out;
-
- rc = SYSCTL_OUT(req,
- (uint64_t *)sc->port.mac_stats.decode_buf + id,
- sizeof(uint64_t));
-out:
+ if ((rc = sfxge_mac_stat_update(sc)) == 0)
+ val = ((uint64_t *)sc->port.mac_stats.decode_buf)[id];
SFXGE_PORT_UNLOCK(&sc->port);
+
+ if (rc == 0)
+ rc = SYSCTL_OUT(req, &val, sizeof(val));
return (rc);
}
@@ -173,28 +172,29 @@ sfxge_port_wanted_fc_handler(SYSCTL_HAND
sc = arg1;
port = &sc->port;
- SFXGE_PORT_LOCK(port);
-
if (req->newptr != NULL) {
if ((error = SYSCTL_IN(req, &fcntl, sizeof(fcntl))) != 0)
- goto out;
-
- if (port->wanted_fc == fcntl)
- goto out;
+ return (error);
- port->wanted_fc = fcntl;
+ SFXGE_PORT_LOCK(port);
- if (port->init_state != SFXGE_PORT_STARTED)
- goto out;
+ if (port->wanted_fc != fcntl) {
+ if (port->init_state == SFXGE_PORT_STARTED)
+ error = efx_mac_fcntl_set(sc->enp,
+ port->wanted_fc,
+ B_TRUE);
+ if (error == 0)
+ port->wanted_fc = fcntl;
+ }
- error = efx_mac_fcntl_set(sc->enp, port->wanted_fc, B_TRUE);
+ SFXGE_PORT_UNLOCK(port);
} else {
- error = SYSCTL_OUT(req, &port->wanted_fc,
- sizeof(port->wanted_fc));
- }
+ SFXGE_PORT_LOCK(port);
+ fcntl = port->wanted_fc;
+ SFXGE_PORT_UNLOCK(port);
-out:
- SFXGE_PORT_UNLOCK(port);
+ error = SYSCTL_OUT(req, &fcntl, sizeof(fcntl));
+ }
return (error);
}
@@ -205,7 +205,6 @@ sfxge_port_link_fc_handler(SYSCTL_HANDLE
struct sfxge_softc *sc;
struct sfxge_port *port;
unsigned int wanted_fc, link_fc;
- int error;
sc = arg1;
port = &sc->port;
@@ -215,10 +214,9 @@ sfxge_port_link_fc_handler(SYSCTL_HANDLE
efx_mac_fcntl_get(sc->enp, &wanted_fc, &link_fc);
else
link_fc = 0;
- error = SYSCTL_OUT(req, &link_fc, sizeof(link_fc));
SFXGE_PORT_UNLOCK(port);
- return (error);
+ return (SYSCTL_OUT(req, &link_fc, sizeof(link_fc)));
}
#endif /* SFXGE_HAVE_PAUSE_MEDIAOPTS */
@@ -499,16 +497,15 @@ sfxge_phy_stat_handler(SYSCTL_HANDLER_AR
struct sfxge_softc *sc = arg1;
unsigned int id = arg2;
int rc;
+ uint32_t val;
SFXGE_PORT_LOCK(&sc->port);
- if ((rc = sfxge_phy_stat_update(sc)) != 0)
- goto out;
-
- rc = SYSCTL_OUT(req,
- (uint32_t *)sc->port.phy_stats.decode_buf + id,
- sizeof(uint32_t));
-out:
+ if ((rc = sfxge_phy_stat_update(sc)) == 0)
+ val = ((uint32_t *)sc->port.phy_stats.decode_buf)[id];
SFXGE_PORT_UNLOCK(&sc->port);
+
+ if (rc == 0)
+ rc = SYSCTL_OUT(req, &val, sizeof(val));
return (rc);
}
More information about the svn-src-all
mailing list