Date: Thu, 4 Apr 2013 18:42:23 +0000 (UTC) From: Alexander Motin <mav@FreeBSD.org> To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r249103 - projects/camlock/sys/cam Message-ID: <201304041842.r34IgNMM059270@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: mav Date: Thu Apr 4 18:42:23 2013 New Revision: 249103 URL: http://svnweb.freebsd.org/changeset/base/249103 Log: - Add lock assertions to every point where reference counters are modified. - When reference counters are reaching zero, add assertions that there are no children items left. - Add a bit more locking to the xptpdperiphtraverse(). Modified: projects/camlock/sys/cam/cam_periph.c projects/camlock/sys/cam/cam_sim.c projects/camlock/sys/cam/cam_xpt.c Modified: projects/camlock/sys/cam/cam_periph.c ============================================================================== --- projects/camlock/sys/cam/cam_periph.c Thu Apr 4 18:00:18 2013 (r249102) +++ projects/camlock/sys/cam/cam_periph.c Thu Apr 4 18:42:23 2013 (r249103) @@ -378,13 +378,10 @@ cam_periph_acquire(struct cam_periph *pe void cam_periph_release_locked_buses(struct cam_periph *periph) { - if (periph->refcount != 0) { - periph->refcount--; - } else { - panic("%s: release of %p when refcount is zero\n ", __func__, - periph); - } - if (periph->refcount == 0 + + mtx_assert(periph->sim->mtx, MA_OWNED); + KASSERT(periph->refcount >= 1, ("periph->refcount >= 1")); + if (--periph->refcount == 0 && (periph->flags & CAM_PERIPH_INVALID)) { camperiphfree(periph); } @@ -583,6 +580,7 @@ cam_periph_invalidate(struct cam_periph { CAM_DEBUG(periph->path, CAM_DEBUG_INFO, ("Periph invalidated\n")); + mtx_assert(periph->sim->mtx, MA_OWNED); /* * We only call this routine the first time a peripheral is * invalidated. @@ -605,6 +603,7 @@ camperiphfree(struct cam_periph *periph) { struct periph_driver **p_drv; + mtx_assert(periph->sim->mtx, MA_OWNED); for (p_drv = periph_drivers; *p_drv != NULL; p_drv++) { if (strcmp((*p_drv)->driver_name, periph->periph_name) == 0) break; Modified: projects/camlock/sys/cam/cam_sim.c ============================================================================== --- projects/camlock/sys/cam/cam_sim.c Thu Apr 4 18:00:18 2013 (r249102) +++ projects/camlock/sys/cam/cam_sim.c Thu Apr 4 18:42:23 2013 (r249103) @@ -106,6 +106,7 @@ cam_sim_free(struct cam_sim *sim, int fr { int error; + mtx_assert(sim->mtx, MA_OWNED); sim->refcount--; if (sim->refcount > 0) { error = msleep(sim, sim->mtx, PRIBIO, "simfree", 0); Modified: projects/camlock/sys/cam/cam_xpt.c ============================================================================== --- projects/camlock/sys/cam/cam_xpt.c Thu Apr 4 18:00:18 2013 (r249102) +++ projects/camlock/sys/cam/cam_xpt.c Thu Apr 4 18:42:23 2013 (r249103) @@ -2038,6 +2038,7 @@ xpttargettraverse(struct cam_eb *bus, st struct cam_et *target, *next_target; int retval; + mtx_assert(bus->sim->mtx, MA_OWNED); retval = 1; for (target = (start_target ? start_target : TAILQ_FIRST(&bus->et_entries)); @@ -2065,6 +2066,7 @@ xptdevicetraverse(struct cam_et *target, struct cam_ed *device, *next_device; int retval; + mtx_assert(target->bus->sim->mtx, MA_OWNED); retval = 1; for (device = (start_device ? start_device : TAILQ_FIRST(&target->ed_entries)); @@ -2103,6 +2105,7 @@ xptperiphtraverse(struct cam_ed *device, retval = 1; + mtx_assert(device->sim->mtx, MA_OWNED); xpt_lock_buses(); for (periph = (start_periph ? start_periph : SLIST_FIRST(&device->periphs)); @@ -2184,6 +2187,7 @@ xptpdperiphtraverse(struct periph_driver xpt_periphfunc_t *tr_func, void *arg) { struct cam_periph *periph, *next_periph; + struct cam_sim *sim; int retval; retval = 1; @@ -2212,7 +2216,10 @@ xptpdperiphtraverse(struct periph_driver * traversal function, so it can't go away. */ periph->refcount++; - + sim = periph->sim; + xpt_unlock_buses(); + CAM_SIM_LOCK(sim); + xpt_lock_buses(); retval = tr_func(periph, arg); /* @@ -2222,6 +2229,7 @@ xptpdperiphtraverse(struct periph_driver next_periph = TAILQ_NEXT(periph, unit_links); cam_periph_release_locked_buses(periph); + CAM_SIM_UNLOCK(sim); if (retval == 0) goto bailout_done; @@ -3461,13 +3469,13 @@ xpt_path_counts(struct cam_path *path, u else *bus_ref = 0; } - xpt_unlock_buses(); if (periph_ref) { if (path->periph) *periph_ref = path->periph->refcount; else *periph_ref = 0; } + xpt_unlock_buses(); if (target_ref) { if (path->target) *target_ref = path->target->refcount; @@ -4300,14 +4308,17 @@ xpt_release_bus(struct cam_eb *bus) xpt_lock_buses(); KASSERT(bus->refcount >= 1, ("bus->refcount >= 1")); - if (--bus->refcount == 0) { - TAILQ_REMOVE(&xsoftc.xpt_busses, bus, links); - xsoftc.bus_generation++; - xpt_unlock_buses(); - cam_sim_release(bus->sim); - free(bus, M_CAMXPT); - } else + if (--bus->refcount > 0) { xpt_unlock_buses(); + return; + } + KASSERT(TAILQ_EMPTY(&bus->et_entries), + ("refcount is zero, but target list is not empty")); + TAILQ_REMOVE(&xsoftc.xpt_busses, bus, links); + xsoftc.bus_generation++; + xpt_unlock_buses(); + cam_sim_release(bus->sim); + free(bus, M_CAMXPT); } static struct cam_et * @@ -4315,6 +4326,7 @@ xpt_alloc_target(struct cam_eb *bus, tar { struct cam_et *cur_target, *target; + mtx_assert(bus->sim->mtx, MA_OWNED); target = (struct cam_et *)malloc(sizeof(*target), M_CAMXPT, M_NOWAIT|M_ZERO); if (target == NULL) @@ -4352,8 +4364,11 @@ static void xpt_release_target(struct cam_et *target) { + mtx_assert(target->bus->sim->mtx, MA_OWNED); if (--target->refcount > 0) return; + KASSERT(TAILQ_EMPTY(&target->ed_entries), + ("refcount is zero, but device list is not empty")); TAILQ_REMOVE(&target->bus->et_entries, target, links); target->bus->generation++; xpt_release_bus(target->bus); @@ -4384,6 +4399,7 @@ xpt_alloc_device(struct cam_eb *bus, str struct cam_devq *devq; cam_status status; + mtx_assert(target->bus->sim->mtx, MA_OWNED); /* Make space for us in the device queue on our bus */ devq = bus->sim->devq; status = cam_devq_resize(devq, devq->send_queue.array_size + 1); @@ -4436,6 +4452,7 @@ void xpt_acquire_device(struct cam_ed *device) { + mtx_assert(device->sim->mtx, MA_OWNED); device->refcount++; } @@ -4444,9 +4461,12 @@ xpt_release_device(struct cam_ed *device { struct cam_devq *devq; + mtx_assert(device->sim->mtx, MA_OWNED); if (--device->refcount > 0) return; + KASSERT(SLIST_EMPTY(&device->periphs), + ("refcount is zero, but periphs list is not empty")); if (device->devq_entry.pinfo.index != CAM_UNQUEUED_INDEX) panic("Removing device while still queued for ccbs"); @@ -4518,6 +4538,7 @@ xpt_find_target(struct cam_eb *bus, targ { struct cam_et *target; + mtx_assert(bus->sim->mtx, MA_OWNED); for (target = TAILQ_FIRST(&bus->et_entries); target != NULL; target = TAILQ_NEXT(target, links)) { @@ -4534,6 +4555,7 @@ xpt_find_device(struct cam_et *target, l { struct cam_ed *device; + mtx_assert(target->bus->sim->mtx, MA_OWNED); for (device = TAILQ_FIRST(&target->ed_entries); device != NULL; device = TAILQ_NEXT(device, links)) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201304041842.r34IgNMM059270>