From owner-svn-src-stable@FreeBSD.ORG Mon Oct 20 07:57:08 2014 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 2FA7AF74; Mon, 20 Oct 2014 07:57:08 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 1B597AD5; Mon, 20 Oct 2014 07:57:08 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id s9K7v7Mk084074; Mon, 20 Oct 2014 07:57:07 GMT (envelope-from mav@FreeBSD.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id s9K7v7f0084073; Mon, 20 Oct 2014 07:57:07 GMT (envelope-from mav@FreeBSD.org) Message-Id: <201410200757.s9K7v7f0084073@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: mav set sender to mav@FreeBSD.org using -f From: Alexander Motin Date: Mon, 20 Oct 2014 07:57:07 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r273317 - stable/10/sys/cam/ctl X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-stable@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: SVN commit messages for all the -stable branches of the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 20 Oct 2014 07:57:08 -0000 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));