From owner-svn-src-stable@FreeBSD.ORG Thu Apr 18 09:40:35 2013 Return-Path: Delivered-To: svn-src-stable@freebsd.org Received: from mx1.freebsd.org (mx1.FreeBSD.org [8.8.178.115]) by hub.freebsd.org (Postfix) with ESMTP id D259595F; Thu, 18 Apr 2013 09:40:35 +0000 (UTC) (envelope-from mav@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id C3D2D8B5; Thu, 18 Apr 2013 09:40:35 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.6/8.14.6) with ESMTP id r3I9eZIM093265; Thu, 18 Apr 2013 09:40:35 GMT (envelope-from mav@svn.freebsd.org) Received: (from mav@localhost) by svn.freebsd.org (8.14.6/8.14.5/Submit) id r3I9eZW0093262; Thu, 18 Apr 2013 09:40:35 GMT (envelope-from mav@svn.freebsd.org) Message-Id: <201304180940.r3I9eZW0093262@svn.freebsd.org> From: Alexander Motin Date: Thu, 18 Apr 2013 09:40:35 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-9@freebsd.org Subject: svn commit: r249610 - in stable/9/sys/cam: . ata scsi X-SVN-Group: stable-9 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.14 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: Thu, 18 Apr 2013 09:40:36 -0000 Author: mav Date: Thu Apr 18 09:40:34 2013 New Revision: 249610 URL: http://svnweb.freebsd.org/changeset/base/249610 Log: MFC r248868, r248874: Implement CAM_PERIPH_FOREACH() macro, safely iterating over the list of driver's periphs, acquiring and releaseing periph references while doing it. Use it to iterate over the lists of ada and da periphs when flushing caches and putting devices to sleep on shutdown and suspend. Previous code could panic in theory if some device disappear in the middle of the process. Modified: stable/9/sys/cam/ata/ata_da.c stable/9/sys/cam/cam_periph.h stable/9/sys/cam/scsi/scsi_da.c Directory Properties: stable/9/sys/ (props changed) Modified: stable/9/sys/cam/ata/ata_da.c ============================================================================== --- stable/9/sys/cam/ata/ata_da.c Thu Apr 18 09:03:06 2013 (r249609) +++ stable/9/sys/cam/ata/ata_da.c Thu Apr 18 09:40:34 2013 (r249610) @@ -1827,7 +1827,7 @@ adaflush(void) struct ada_softc *softc; int error; - TAILQ_FOREACH(periph, &adadriver.units, unit_links) { + CAM_PERIPH_FOREACH(periph, &adadriver) { union ccb ccb; /* If we paniced with lock held - not recurse here. */ @@ -1881,7 +1881,7 @@ adaspindown(uint8_t cmd, int flags) struct ada_softc *softc; int error; - TAILQ_FOREACH(periph, &adadriver.units, unit_links) { + CAM_PERIPH_FOREACH(periph, &adadriver) { union ccb ccb; /* If we paniced with lock held - not recurse here. */ @@ -1954,7 +1954,7 @@ adaresume(void *arg) if (ada_spindown_suspend == 0) return; - TAILQ_FOREACH(periph, &adadriver.units, unit_links) { + CAM_PERIPH_FOREACH(periph, &adadriver) { cam_periph_lock(periph); softc = (struct ada_softc *)periph->softc; /* Modified: stable/9/sys/cam/cam_periph.h ============================================================================== --- stable/9/sys/cam/cam_periph.h Thu Apr 18 09:03:06 2013 (r249609) +++ stable/9/sys/cam/cam_periph.h Thu Apr 18 09:40:34 2013 (r249610) @@ -36,6 +36,8 @@ #ifdef _KERNEL +#include + struct devstat; extern struct cam_periph *xpt_periph; @@ -209,5 +211,42 @@ cam_periph_sleep(struct cam_periph *peri return (msleep(chan, periph->sim->mtx, priority, wmesg, timo)); } +static inline struct cam_periph * +cam_periph_acquire_first(struct periph_driver *driver) +{ + struct cam_periph *periph; + + xpt_lock_buses(); + periph = TAILQ_FIRST(&driver->units); + while (periph != NULL && (periph->flags & CAM_PERIPH_INVALID) != 0) + periph = TAILQ_NEXT(periph, unit_links); + if (periph != NULL) + periph->refcount++; + xpt_unlock_buses(); + return (periph); +} + +static inline struct cam_periph * +cam_periph_acquire_next(struct cam_periph *pperiph) +{ + struct cam_periph *periph = pperiph; + + mtx_assert(pperiph->sim->mtx, MA_NOTOWNED); + xpt_lock_buses(); + do { + periph = TAILQ_NEXT(periph, unit_links); + } while (periph != NULL && (periph->flags & CAM_PERIPH_INVALID) != 0); + if (periph != NULL) + periph->refcount++; + xpt_unlock_buses(); + cam_periph_release(pperiph); + return (periph); +} + +#define CAM_PERIPH_FOREACH(periph, driver) \ + for ((periph) = cam_periph_acquire_first(driver); \ + (periph) != NULL; \ + (periph) = cam_periph_acquire_next(periph)) + #endif /* _KERNEL */ #endif /* _CAM_CAM_PERIPH_H */ Modified: stable/9/sys/cam/scsi/scsi_da.c ============================================================================== --- stable/9/sys/cam/scsi/scsi_da.c Thu Apr 18 09:03:06 2013 (r249609) +++ stable/9/sys/cam/scsi/scsi_da.c Thu Apr 18 09:40:34 2013 (r249610) @@ -2836,7 +2836,7 @@ dashutdown(void * arg, int howto) struct da_softc *softc; int error; - TAILQ_FOREACH(periph, &dadriver.units, unit_links) { + CAM_PERIPH_FOREACH(periph, &dadriver) { union ccb ccb; cam_periph_lock(periph);