From owner-svn-src-all@FreeBSD.ORG Tue Jun 8 22:46:44 2010 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id B5870106564A; Tue, 8 Jun 2010 22:46:44 +0000 (UTC) (envelope-from mjacob@FreeBSD.org) Received: from svn.freebsd.org (unknown [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id A49F58FC13; Tue, 8 Jun 2010 22:46:44 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id o58MkijA036474; Tue, 8 Jun 2010 22:46:44 GMT (envelope-from mjacob@svn.freebsd.org) Received: (from mjacob@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id o58MkiSf036472; Tue, 8 Jun 2010 22:46:44 GMT (envelope-from mjacob@svn.freebsd.org) Message-Id: <201006082246.o58MkiSf036472@svn.freebsd.org> From: Matt Jacob Date: Tue, 8 Jun 2010 22:46:44 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r208928 - head/sys/cam/scsi X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 08 Jun 2010 22:46:44 -0000 Author: mjacob Date: Tue Jun 8 22:46:44 2010 New Revision: 208928 URL: http://svn.freebsd.org/changeset/base/208928 Log: Rearrange how things are done to avoid dereferencing stale pointers in the case of immediate unconfigure after configure. Hold the periph an extra count while we have the task to create sysctl context outstanding so that the periph doesn't go away unexpectedly. Sponsored by: Panasas Reviewed by: scsi@ MFC after: 1 month Modified: head/sys/cam/scsi/scsi_da.c Modified: head/sys/cam/scsi/scsi_da.c ============================================================================== --- head/sys/cam/scsi/scsi_da.c Tue Jun 8 22:40:02 2010 (r208927) +++ head/sys/cam/scsi/scsi_da.c Tue Jun 8 22:46:44 2010 (r208928) @@ -998,11 +998,6 @@ dacleanup(struct cam_periph *periph) xpt_print(periph->path, "can't remove sysctl context\n"); } - /* - * Nullify our periph pointer here to try and catch - * race conditions in callbacks/downcalls. - */ - softc->disk->d_drv1 = NULL; disk_destroy(softc->disk); callout_drain(&softc->sendordered_c); free(softc, M_DEVBUF); @@ -1082,8 +1077,13 @@ dasysctlinit(void *context, int pending) struct ccb_trans_settings cts; periph = (struct cam_periph *)context; - if (cam_periph_acquire(periph) != CAM_REQ_CMP) + /* + * periph was held for us when this task was enqueued + */ + if (periph->flags & CAM_PERIPH_INVALID) { + cam_periph_release(periph); return; + } softc = (struct da_softc *)periph->softc; snprintf(tmpstr, sizeof(tmpstr), "CAM DA unit %d", periph->unit_number); @@ -1263,29 +1263,6 @@ daregister(struct cam_periph *periph, vo * Register this media as a disk */ - mtx_unlock(periph->sim->mtx); - softc->disk = disk_alloc(); - softc->disk->d_open = daopen; - softc->disk->d_close = daclose; - softc->disk->d_strategy = dastrategy; - softc->disk->d_dump = dadump; - softc->disk->d_name = "da"; - softc->disk->d_drv1 = periph; - if (cpi.maxio == 0) - softc->disk->d_maxsize = DFLTPHYS; /* traditional default */ - else if (cpi.maxio > MAXPHYS) - softc->disk->d_maxsize = MAXPHYS; /* for safety */ - else - softc->disk->d_maxsize = cpi.maxio; - softc->disk->d_unit = periph->unit_number; - softc->disk->d_flags = 0; - if ((softc->quirks & DA_Q_NO_SYNC_CACHE) == 0) - softc->disk->d_flags |= DISKFLAG_CANFLUSHCACHE; - strlcpy(softc->disk->d_ident, cgd->serial_num, - MIN(sizeof(softc->disk->d_ident), cgd->serial_num_len + 1)); - disk_create(softc->disk, DISK_VERSION); - mtx_lock(periph->sim->mtx); - /* * Add async callbacks for bus reset and * bus device reset calls. I don't bother @@ -1303,7 +1280,6 @@ daregister(struct cam_periph *periph, vo * the end of probe. */ (void)cam_periph_hold(periph, PRIBIO); - xpt_schedule(periph, CAM_PRIORITY_DEV); /* * Schedule a periodic event to occasionally send an @@ -1314,6 +1290,31 @@ daregister(struct cam_periph *periph, vo (DA_DEFAULT_TIMEOUT * hz) / DA_ORDEREDTAG_INTERVAL, dasendorderedtag, softc); + mtx_unlock(periph->sim->mtx); + softc->disk = disk_alloc(); + softc->disk->d_open = daopen; + softc->disk->d_close = daclose; + softc->disk->d_strategy = dastrategy; + softc->disk->d_dump = dadump; + softc->disk->d_name = "da"; + softc->disk->d_drv1 = periph; + if (cpi.maxio == 0) + softc->disk->d_maxsize = DFLTPHYS; /* traditional default */ + else if (cpi.maxio > MAXPHYS) + softc->disk->d_maxsize = MAXPHYS; /* for safety */ + else + softc->disk->d_maxsize = cpi.maxio; + softc->disk->d_unit = periph->unit_number; + softc->disk->d_flags = 0; + if ((softc->quirks & DA_Q_NO_SYNC_CACHE) == 0) + softc->disk->d_flags |= DISKFLAG_CANFLUSHCACHE; + strlcpy(softc->disk->d_ident, cgd->serial_num, + MIN(sizeof(softc->disk->d_ident), cgd->serial_num_len + 1)); + disk_create(softc->disk, DISK_VERSION); + mtx_lock(periph->sim->mtx); + + xpt_schedule(periph, CAM_PRIORITY_DEV); + return(CAM_REQ_CMP); } @@ -1773,6 +1774,7 @@ dadone(struct cam_periph *periph, union * Create our sysctl variables, now that we know * we have successfully attached. */ + (void) cam_periph_acquire(periph); /* increase the refcount */ taskqueue_enqueue(taskqueue_thread,&softc->sysctl_task); } softc->state = DA_STATE_NORMAL;