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.
This commit is contained in:
parent
bb829be508
commit
7d9cb4d9ab
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=272938
@ -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 code, struct cam_path *path, void *arg)
|
||||
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 code, struct cam_path *path, void *arg)
|
||||
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 code, struct cam_path *path, void *arg)
|
||||
* 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 code, struct cam_path *path, void *arg)
|
||||
|
||||
/* 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 code, struct cam_path *path, void *arg)
|
||||
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 code, struct cam_path *path, void *arg)
|
||||
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 code, struct cam_path *path, void *arg)
|
||||
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));
|
||||
|
Loading…
Reference in New Issue
Block a user