svn commit: r249103 - projects/camlock/sys/cam
Alexander Motin
mav at FreeBSD.org
Thu Apr 4 18:42:24 UTC 2013
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)) {
More information about the svn-src-projects
mailing list