svn commit: r273317 - stable/10/sys/cam/ctl
Alexander Motin
mav at FreeBSD.org
Mon Oct 20 07:57:08 UTC 2014
Author: mav
Date: Mon Oct 20 07:57:07 2014
New Revision: 273317
URL: https://svnweb.freebsd.org/changeset/base/273317
Log:
MFC r272938: Filter out duplicate AC_PATH_REGISTERED async events.
Queued async events handling in CAM opened race, that may lead to duplicate
AC_PATH_REGISTERED events delivery during boot. That was not happening
before r272935 because the driver was initialized later. After that change
it started create duplicate ports in CTL.
Modified:
stable/10/sys/cam/ctl/scsi_ctl.c
Directory Properties:
stable/10/ (props changed)
Modified: stable/10/sys/cam/ctl/scsi_ctl.c
==============================================================================
--- stable/10/sys/cam/ctl/scsi_ctl.c Mon Oct 20 07:52:48 2014 (r273316)
+++ stable/10/sys/cam/ctl/scsi_ctl.c Mon Oct 20 07:57:07 2014 (r273317)
@@ -271,11 +271,19 @@ ctlfeperiphinit(void)
static void
ctlfeasync(void *callback_arg, uint32_t code, struct cam_path *path, void *arg)
{
+ struct ctlfe_softc *softc;
#ifdef CTLFEDEBUG
printf("%s: entered\n", __func__);
#endif
+ mtx_lock(&ctlfe_list_mtx);
+ STAILQ_FOREACH(softc, &ctlfe_softc_list, links) {
+ if (softc->path_id == xpt_path_path_id(path))
+ break;
+ }
+ mtx_unlock(&ctlfe_list_mtx);
+
/*
* When a new path gets registered, and it is capable of target
* mode, go ahead and attach. Later on, we may need to be more
@@ -284,7 +292,6 @@ ctlfeasync(void *callback_arg, uint32_t
switch (code) {
case AC_PATH_REGISTERED: {
struct ctl_port *port;
- struct ctlfe_softc *bus_softc;
struct ccb_pathinq *cpi;
int retval;
@@ -299,6 +306,14 @@ ctlfeasync(void *callback_arg, uint32_t
break;
}
+ if (softc != NULL) {
+#ifdef CTLFEDEBUG
+ printf("%s: CTL port for CAM path %u already exists\n",
+ __func__, xpt_path_path_id(path));
+#endif
+ break;
+ }
+
#ifdef CTLFE_INIT_ENABLE
if (ctlfe_num_targets >= ctlfe_max_targets) {
union ccb *ccb;
@@ -347,25 +362,23 @@ ctlfeasync(void *callback_arg, uint32_t
* use M_NOWAIT. Of course this means trouble if we
* can't allocate memory.
*/
- bus_softc = malloc(sizeof(*bus_softc), M_CTLFE,
- M_NOWAIT | M_ZERO);
- if (bus_softc == NULL) {
+ softc = malloc(sizeof(*softc), M_CTLFE, M_NOWAIT | M_ZERO);
+ if (softc == NULL) {
printf("%s: unable to malloc %zd bytes for softc\n",
- __func__, sizeof(*bus_softc));
+ __func__, sizeof(*softc));
return;
}
- bus_softc->path_id = cpi->ccb_h.path_id;
- bus_softc->sim = xpt_path_sim(path);
+ softc->path_id = cpi->ccb_h.path_id;
+ softc->sim = xpt_path_sim(path);
if (cpi->maxio != 0)
- bus_softc->maxio = cpi->maxio;
+ softc->maxio = cpi->maxio;
else
- bus_softc->maxio = DFLTPHYS;
- mtx_init(&bus_softc->lun_softc_mtx, "LUN softc mtx", NULL,
- MTX_DEF);
- STAILQ_INIT(&bus_softc->lun_softc_list);
+ softc->maxio = DFLTPHYS;
+ mtx_init(&softc->lun_softc_mtx, "LUN softc mtx", NULL, MTX_DEF);
+ STAILQ_INIT(&softc->lun_softc_list);
- port = &bus_softc->port;
+ port = &softc->port;
port->frontend = &ctlfe_frontend;
/*
@@ -380,21 +393,21 @@ ctlfeasync(void *callback_arg, uint32_t
/* XXX KDM what should the real number be here? */
port->num_requested_ctl_io = 4096;
- snprintf(bus_softc->port_name, sizeof(bus_softc->port_name),
+ snprintf(softc->port_name, sizeof(softc->port_name),
"%s%d", cpi->dev_name, cpi->unit_number);
/*
* XXX KDM it would be nice to allocate storage in the
* frontend structure itself.
*/
- port->port_name = bus_softc->port_name;
+ port->port_name = softc->port_name;
port->physical_port = cpi->unit_number;
port->virtual_port = cpi->bus_id;
port->port_online = ctlfe_online;
port->port_offline = ctlfe_offline;
- port->onoff_arg = bus_softc;
+ port->onoff_arg = softc;
port->lun_enable = ctlfe_lun_enable;
port->lun_disable = ctlfe_lun_disable;
- port->targ_lun_arg = bus_softc;
+ port->targ_lun_arg = softc;
port->fe_datamove = ctlfe_datamove_done;
port->fe_done = ctlfe_datamove_done;
/*
@@ -416,35 +429,28 @@ ctlfeasync(void *callback_arg, uint32_t
if (retval != 0) {
printf("%s: ctl_port_register() failed with "
"error %d!\n", __func__, retval);
- mtx_destroy(&bus_softc->lun_softc_mtx);
- free(bus_softc, M_CTLFE);
+ mtx_destroy(&softc->lun_softc_mtx);
+ free(softc, M_CTLFE);
break;
} else {
mtx_lock(&ctlfe_list_mtx);
- STAILQ_INSERT_TAIL(&ctlfe_softc_list, bus_softc, links);
+ STAILQ_INSERT_TAIL(&ctlfe_softc_list, softc, links);
mtx_unlock(&ctlfe_list_mtx);
}
break;
}
case AC_PATH_DEREGISTERED: {
- struct ctlfe_softc *softc = NULL;
-
- mtx_lock(&ctlfe_list_mtx);
- STAILQ_FOREACH(softc, &ctlfe_softc_list, links) {
- if (softc->path_id == xpt_path_path_id(path)) {
- STAILQ_REMOVE(&ctlfe_softc_list, softc,
- ctlfe_softc, links);
- break;
- }
- }
- mtx_unlock(&ctlfe_list_mtx);
if (softc != NULL) {
/*
* XXX KDM are we certain at this point that there
* are no outstanding commands for this frontend?
*/
+ mtx_lock(&ctlfe_list_mtx);
+ STAILQ_REMOVE(&ctlfe_softc_list, softc, ctlfe_softc,
+ links);
+ mtx_unlock(&ctlfe_list_mtx);
ctl_port_deregister(&softc->port);
mtx_destroy(&softc->lun_softc_mtx);
free(softc, M_CTLFE);
@@ -459,8 +465,7 @@ ctlfeasync(void *callback_arg, uint32_t
switch (ac->contract_number) {
case AC_CONTRACT_DEV_CHG: {
struct ac_device_changed *dev_chg;
- struct ctlfe_softc *softc;
- int retval, found;
+ int retval;
dev_chg = (struct ac_device_changed *)ac->contract_data;
@@ -469,18 +474,7 @@ ctlfeasync(void *callback_arg, uint32_t
xpt_path_path_id(path), dev_chg->target,
(dev_chg->arrived == 0) ? "left" : "arrived");
- found = 0;
-
- mtx_lock(&ctlfe_list_mtx);
- STAILQ_FOREACH(softc, &ctlfe_softc_list, links) {
- if (softc->path_id == xpt_path_path_id(path)) {
- found = 1;
- break;
- }
- }
- mtx_unlock(&ctlfe_list_mtx);
-
- if (found == 0) {
+ if (softc == NULL) {
printf("%s: CTL port for CAM path %u not "
"found!\n", __func__,
xpt_path_path_id(path));
More information about the svn-src-stable-10
mailing list