Change t4_list_lock and t4_uld_list_lock from mutexes to sx'es.
- tom_uninit had to be reworked not to hold the adapter lock (a mutex) around t4_deactivate_uld, which acquires the uld_list_lock. - the ifc_match for the interface cloner that creates the tracer ifnet had to be reworked as the kernel calls ifc_match with the global if_cloners_mtx held.
This commit is contained in:
parent
9800517691
commit
319a31ea18
@ -160,10 +160,10 @@ MALLOC_DEFINE(M_CXGBE, "cxgbe", "Chelsio T4/T5 Ethernet driver and services");
|
|||||||
* Correct lock order when you need to acquire multiple locks is t4_list_lock,
|
* Correct lock order when you need to acquire multiple locks is t4_list_lock,
|
||||||
* then ADAPTER_LOCK, then t4_uld_list_lock.
|
* then ADAPTER_LOCK, then t4_uld_list_lock.
|
||||||
*/
|
*/
|
||||||
static struct mtx t4_list_lock;
|
static struct sx t4_list_lock;
|
||||||
static SLIST_HEAD(, adapter) t4_list;
|
static SLIST_HEAD(, adapter) t4_list;
|
||||||
#ifdef TCP_OFFLOAD
|
#ifdef TCP_OFFLOAD
|
||||||
static struct mtx t4_uld_list_lock;
|
static struct sx t4_uld_list_lock;
|
||||||
static SLIST_HEAD(, uld_info) t4_uld_list;
|
static SLIST_HEAD(, uld_info) t4_uld_list;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -568,9 +568,9 @@ t4_attach(device_t dev)
|
|||||||
snprintf(sc->lockname, sizeof(sc->lockname), "%s",
|
snprintf(sc->lockname, sizeof(sc->lockname), "%s",
|
||||||
device_get_nameunit(dev));
|
device_get_nameunit(dev));
|
||||||
mtx_init(&sc->sc_lock, sc->lockname, 0, MTX_DEF);
|
mtx_init(&sc->sc_lock, sc->lockname, 0, MTX_DEF);
|
||||||
mtx_lock(&t4_list_lock);
|
sx_xlock(&t4_list_lock);
|
||||||
SLIST_INSERT_HEAD(&t4_list, sc, link);
|
SLIST_INSERT_HEAD(&t4_list, sc, link);
|
||||||
mtx_unlock(&t4_list_lock);
|
sx_xunlock(&t4_list_lock);
|
||||||
|
|
||||||
mtx_init(&sc->sfl_lock, "starving freelists", 0, MTX_DEF);
|
mtx_init(&sc->sfl_lock, "starving freelists", 0, MTX_DEF);
|
||||||
TAILQ_INIT(&sc->sfl);
|
TAILQ_INIT(&sc->sfl);
|
||||||
@ -917,9 +917,9 @@ t4_detach(device_t dev)
|
|||||||
free(sc->tids.ftid_tab, M_CXGBE);
|
free(sc->tids.ftid_tab, M_CXGBE);
|
||||||
t4_destroy_dma_tag(sc);
|
t4_destroy_dma_tag(sc);
|
||||||
if (mtx_initialized(&sc->sc_lock)) {
|
if (mtx_initialized(&sc->sc_lock)) {
|
||||||
mtx_lock(&t4_list_lock);
|
sx_xlock(&t4_list_lock);
|
||||||
SLIST_REMOVE(&t4_list, sc, adapter, link);
|
SLIST_REMOVE(&t4_list, sc, adapter, link);
|
||||||
mtx_unlock(&t4_list_lock);
|
sx_xunlock(&t4_list_lock);
|
||||||
mtx_destroy(&sc->sc_lock);
|
mtx_destroy(&sc->sc_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7341,7 +7341,7 @@ t4_iterate(void (*func)(struct adapter *, void *), void *arg)
|
|||||||
{
|
{
|
||||||
struct adapter *sc;
|
struct adapter *sc;
|
||||||
|
|
||||||
mtx_lock(&t4_list_lock);
|
sx_slock(&t4_list_lock);
|
||||||
SLIST_FOREACH(sc, &t4_list, link) {
|
SLIST_FOREACH(sc, &t4_list, link) {
|
||||||
/*
|
/*
|
||||||
* func should not make any assumptions about what state sc is
|
* func should not make any assumptions about what state sc is
|
||||||
@ -7349,7 +7349,7 @@ t4_iterate(void (*func)(struct adapter *, void *), void *arg)
|
|||||||
*/
|
*/
|
||||||
func(sc, arg);
|
func(sc, arg);
|
||||||
}
|
}
|
||||||
mtx_unlock(&t4_list_lock);
|
sx_sunlock(&t4_list_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -7577,7 +7577,7 @@ t4_register_uld(struct uld_info *ui)
|
|||||||
int rc = 0;
|
int rc = 0;
|
||||||
struct uld_info *u;
|
struct uld_info *u;
|
||||||
|
|
||||||
mtx_lock(&t4_uld_list_lock);
|
sx_xlock(&t4_uld_list_lock);
|
||||||
SLIST_FOREACH(u, &t4_uld_list, link) {
|
SLIST_FOREACH(u, &t4_uld_list, link) {
|
||||||
if (u->uld_id == ui->uld_id) {
|
if (u->uld_id == ui->uld_id) {
|
||||||
rc = EEXIST;
|
rc = EEXIST;
|
||||||
@ -7588,7 +7588,7 @@ t4_register_uld(struct uld_info *ui)
|
|||||||
SLIST_INSERT_HEAD(&t4_uld_list, ui, link);
|
SLIST_INSERT_HEAD(&t4_uld_list, ui, link);
|
||||||
ui->refcount = 0;
|
ui->refcount = 0;
|
||||||
done:
|
done:
|
||||||
mtx_unlock(&t4_uld_list_lock);
|
sx_xunlock(&t4_uld_list_lock);
|
||||||
return (rc);
|
return (rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7598,7 +7598,7 @@ t4_unregister_uld(struct uld_info *ui)
|
|||||||
int rc = EINVAL;
|
int rc = EINVAL;
|
||||||
struct uld_info *u;
|
struct uld_info *u;
|
||||||
|
|
||||||
mtx_lock(&t4_uld_list_lock);
|
sx_xlock(&t4_uld_list_lock);
|
||||||
|
|
||||||
SLIST_FOREACH(u, &t4_uld_list, link) {
|
SLIST_FOREACH(u, &t4_uld_list, link) {
|
||||||
if (u == ui) {
|
if (u == ui) {
|
||||||
@ -7613,7 +7613,7 @@ t4_unregister_uld(struct uld_info *ui)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
done:
|
done:
|
||||||
mtx_unlock(&t4_uld_list_lock);
|
sx_xunlock(&t4_uld_list_lock);
|
||||||
return (rc);
|
return (rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7625,7 +7625,7 @@ t4_activate_uld(struct adapter *sc, int id)
|
|||||||
|
|
||||||
ASSERT_SYNCHRONIZED_OP(sc);
|
ASSERT_SYNCHRONIZED_OP(sc);
|
||||||
|
|
||||||
mtx_lock(&t4_uld_list_lock);
|
sx_slock(&t4_uld_list_lock);
|
||||||
|
|
||||||
SLIST_FOREACH(ui, &t4_uld_list, link) {
|
SLIST_FOREACH(ui, &t4_uld_list, link) {
|
||||||
if (ui->uld_id == id) {
|
if (ui->uld_id == id) {
|
||||||
@ -7636,7 +7636,7 @@ t4_activate_uld(struct adapter *sc, int id)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
done:
|
done:
|
||||||
mtx_unlock(&t4_uld_list_lock);
|
sx_sunlock(&t4_uld_list_lock);
|
||||||
|
|
||||||
return (rc);
|
return (rc);
|
||||||
}
|
}
|
||||||
@ -7649,7 +7649,7 @@ t4_deactivate_uld(struct adapter *sc, int id)
|
|||||||
|
|
||||||
ASSERT_SYNCHRONIZED_OP(sc);
|
ASSERT_SYNCHRONIZED_OP(sc);
|
||||||
|
|
||||||
mtx_lock(&t4_uld_list_lock);
|
sx_slock(&t4_uld_list_lock);
|
||||||
|
|
||||||
SLIST_FOREACH(ui, &t4_uld_list, link) {
|
SLIST_FOREACH(ui, &t4_uld_list, link) {
|
||||||
if (ui->uld_id == id) {
|
if (ui->uld_id == id) {
|
||||||
@ -7660,7 +7660,7 @@ t4_deactivate_uld(struct adapter *sc, int id)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
done:
|
done:
|
||||||
mtx_unlock(&t4_uld_list_lock);
|
sx_sunlock(&t4_uld_list_lock);
|
||||||
|
|
||||||
return (rc);
|
return (rc);
|
||||||
}
|
}
|
||||||
@ -7741,10 +7741,10 @@ mod_event(module_t mod, int cmd, void *arg)
|
|||||||
if (atomic_fetchadd_int(&loaded, 1))
|
if (atomic_fetchadd_int(&loaded, 1))
|
||||||
break;
|
break;
|
||||||
t4_sge_modload();
|
t4_sge_modload();
|
||||||
mtx_init(&t4_list_lock, "T4 adapters", 0, MTX_DEF);
|
sx_init(&t4_list_lock, "T4/T5 adapters");
|
||||||
SLIST_INIT(&t4_list);
|
SLIST_INIT(&t4_list);
|
||||||
#ifdef TCP_OFFLOAD
|
#ifdef TCP_OFFLOAD
|
||||||
mtx_init(&t4_uld_list_lock, "T4 ULDs", 0, MTX_DEF);
|
sx_init(&t4_uld_list_lock, "T4/T5 ULDs");
|
||||||
SLIST_INIT(&t4_uld_list);
|
SLIST_INIT(&t4_uld_list);
|
||||||
#endif
|
#endif
|
||||||
t4_tracer_modload();
|
t4_tracer_modload();
|
||||||
@ -7756,23 +7756,23 @@ mod_event(module_t mod, int cmd, void *arg)
|
|||||||
break;
|
break;
|
||||||
t4_tracer_modunload();
|
t4_tracer_modunload();
|
||||||
#ifdef TCP_OFFLOAD
|
#ifdef TCP_OFFLOAD
|
||||||
mtx_lock(&t4_uld_list_lock);
|
sx_slock(&t4_uld_list_lock);
|
||||||
if (!SLIST_EMPTY(&t4_uld_list)) {
|
if (!SLIST_EMPTY(&t4_uld_list)) {
|
||||||
rc = EBUSY;
|
rc = EBUSY;
|
||||||
mtx_unlock(&t4_uld_list_lock);
|
sx_sunlock(&t4_uld_list_lock);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
mtx_unlock(&t4_uld_list_lock);
|
sx_sunlock(&t4_uld_list_lock);
|
||||||
mtx_destroy(&t4_uld_list_lock);
|
sx_destroy(&t4_uld_list_lock);
|
||||||
#endif
|
#endif
|
||||||
mtx_lock(&t4_list_lock);
|
sx_slock(&t4_list_lock);
|
||||||
if (!SLIST_EMPTY(&t4_list)) {
|
if (!SLIST_EMPTY(&t4_list)) {
|
||||||
rc = EBUSY;
|
rc = EBUSY;
|
||||||
mtx_unlock(&t4_list_lock);
|
sx_sunlock(&t4_list_lock);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
mtx_unlock(&t4_list_lock);
|
sx_sunlock(&t4_list_lock);
|
||||||
mtx_destroy(&t4_list_lock);
|
sx_destroy(&t4_list_lock);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,14 +121,13 @@ match_name(struct adapter *sc, void *arg)
|
|||||||
static int
|
static int
|
||||||
t4_cloner_match(struct if_clone *ifc, const char *name)
|
t4_cloner_match(struct if_clone *ifc, const char *name)
|
||||||
{
|
{
|
||||||
struct match_rr mrr;
|
|
||||||
|
|
||||||
mrr.name = name;
|
if (strncmp(name, "t4nex", 5) != 0 &&
|
||||||
mrr.lock = 0;
|
strncmp(name, "t5nex", 5) != 0)
|
||||||
mrr.sc = NULL;
|
return (0);
|
||||||
t4_iterate(match_name, &mrr);
|
if (name[5] < '0' || name[5] > '9')
|
||||||
|
return (0);
|
||||||
return (mrr.sc != NULL);
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
@ -1064,14 +1064,14 @@ t4_tom_mod_load(void)
|
|||||||
static void
|
static void
|
||||||
tom_uninit(struct adapter *sc, void *arg __unused)
|
tom_uninit(struct adapter *sc, void *arg __unused)
|
||||||
{
|
{
|
||||||
if (begin_synchronized_op(sc, NULL, HOLD_LOCK, "t4tomun"))
|
if (begin_synchronized_op(sc, NULL, SLEEP_OK | INTR_OK, "t4tomun"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Try to free resources (works only if no port has IFCAP_TOE) */
|
/* Try to free resources (works only if no port has IFCAP_TOE) */
|
||||||
if (sc->flags & TOM_INIT_DONE)
|
if (sc->flags & TOM_INIT_DONE)
|
||||||
t4_deactivate_uld(sc, ULD_TOM);
|
t4_deactivate_uld(sc, ULD_TOM);
|
||||||
|
|
||||||
end_synchronized_op(sc, LOCK_HELD);
|
end_synchronized_op(sc, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
|
Loading…
x
Reference in New Issue
Block a user