Date: Wed, 24 Aug 2005 22:13:49 GMT From: Scott Long <scottl@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 82512 for review Message-ID: <200508242213.j7OMDnWj080928@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=82512 Change 82512 by scottl@scottl-junior on 2005/08/24 22:12:48 Start adding the topology lock to cam_periph.c. This covers reference counting of the periph as well as global periph list operations. Affected files ... .. //depot/projects/scottl-camlock/src/sys/cam/cam_periph.c#5 edit Differences ... ==== //depot/projects/scottl-camlock/src/sys/cam/cam_periph.c#5 (text+ko) ==== @@ -121,7 +121,6 @@ lun_id_t lun_id; cam_status status; u_int init_level; - int s; init_level = 0; /* @@ -186,7 +185,7 @@ if (status != CAM_REQ_CMP) goto failure; - s = splsoftcam(); + mtx_lock(&cam_topo_lock); cur_periph = TAILQ_FIRST(&(*p_drv)->units); while (cur_periph != NULL && cur_periph->unit_number < periph->unit_number) @@ -198,9 +197,8 @@ TAILQ_INSERT_TAIL(&(*p_drv)->units, periph, unit_links); (*p_drv)->generation++; } + mtx_unlock(&cam_topo_lock); - splx(s); - init_level++; status = periph_ctor(periph, arg); @@ -214,9 +212,9 @@ /* Initialized successfully */ break; case 3: - s = splsoftcam(); + mtx_lock(&cam_topo_lock); TAILQ_REMOVE(&(*p_drv)->units, periph, unit_links); - splx(s); + mtx_unlock(&cam_topo_lock); xpt_remove_periph(periph); /* FALLTHROUGH */ case 2: @@ -244,21 +242,20 @@ { struct periph_driver **p_drv; struct cam_periph *periph; - int s; for (p_drv = periph_drivers; *p_drv != NULL; p_drv++) { if (name != NULL && (strcmp((*p_drv)->driver_name, name) != 0)) continue; - s = splsoftcam(); + mtx_lock(&cam_topo_lock); TAILQ_FOREACH(periph, &(*p_drv)->units, unit_links) { if (xpt_path_comp(periph->path, path) == 0) { - splx(s); + mtx_unlock(&cam_topo_lock); return(periph); } } - splx(s); + mtx_unlock(&cam_topo_lock); if (name != NULL) return(NULL); } @@ -268,14 +265,14 @@ cam_status cam_periph_acquire(struct cam_periph *periph) { - int s; if (periph == NULL) return(CAM_REQ_CMP_ERR); - s = splsoftcam(); + /* XXX atomic increment instead? */ + mtx_lock(&cam_topo_lock); periph->refcount++; - splx(s); + mtx_unlock(&cam_topo_lock); return(CAM_REQ_CMP); } @@ -283,17 +280,17 @@ void cam_periph_release(struct cam_periph *periph) { - int s; if (periph == NULL) return; - s = splsoftcam(); + /* camperiphfree() will release the mutex. */ + mtx_lock(&cam_topo_lock); if ((--periph->refcount == 0) && (periph->flags & CAM_PERIPH_INVALID)) { camperiphfree(periph); - } - splx(s); + } else + mtx_unlock(&cam_topo_lock); } @@ -311,11 +308,10 @@ { struct cam_periph *periph; char *periph_name; - int s; int i, val, dunit, r; const char *dname, *strval; - s = splsoftcam(); + mtx_lock(&cam_topo_lock); periph_name = p_drv->driver_name; for (;;newunit++) { @@ -361,7 +357,7 @@ if (r != 0) break; } - splx(s); + mtx_unlock(&cam_topo_lock); return (newunit); } @@ -418,7 +414,6 @@ { int s; - s = splsoftcam(); /* * We only call this routine the first time a peripheral is * invalidated. The oninvalidate() routine is always called at @@ -431,36 +426,43 @@ periph->flags |= CAM_PERIPH_INVALID; periph->flags &= ~CAM_PERIPH_NEW_DEV_FOUND; + /* camperiphfree() will release the mutex. */ + mtx_lock(&cam_topo_lock); if (periph->refcount == 0) camperiphfree(periph); - else if (periph->refcount < 0) + else if (periph->refcount < 0) { + mtx_unlock(&cam_topo_lock); printf("cam_invalidate_periph: refcount < 0!!\n"); - splx(s); + } } +/* + * The topology lock must be held on entry and will be released before return. + */ static void camperiphfree(struct cam_periph *periph) { - int s; struct periph_driver **p_drv; + mtx_assert(&cam_topo_lock, MTX_OWNED); + for (p_drv = periph_drivers; *p_drv != NULL; p_drv++) { - if (strcmp((*p_drv)->driver_name, periph->periph_name) == 0) + if (strcmp((*p_drv)->driver_name, periph->periph_name) == 0) { + TAILQ_REMOVE(&(*p_drv)->units, periph, unit_links); + (*p_drv)->generation++; break; + } } + mtx_unlock(&cam_topo_lock); + if (*p_drv == NULL) { printf("camperiphfree: attempt to free non-existant periph\n"); return; } - + if (periph->periph_dtor != NULL) periph->periph_dtor(periph); - s = splsoftcam(); - TAILQ_REMOVE(&(*p_drv)->units, periph, unit_links); - (*p_drv)->generation++; - splx(s); - xpt_remove_periph(periph); if (periph->flags & CAM_PERIPH_NEW_DEV_FOUND) {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200508242213.j7OMDnWj080928>