svn commit: r249610 - in stable/9/sys/cam: . ata scsi
Alexander Motin
mav at FreeBSD.org
Thu Apr 18 09:40:36 UTC 2013
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 <cam/cam_xpt.h>
+
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);
More information about the svn-src-stable-9
mailing list