Restore the CAM XPT peripheral generation counter, and export it via sysctl.

Define it as an atomic uint32_t.  These increments happen infrequently
enough for the atomic overhead to be a problem, and since they're now
independent atomics, they won't contend with xpt_lock_buses().

This counter is useful as a means of cheaply identifying whether any changes
have been made to the CAM peripheral list.  Userland programs have no guarantee
that the counter won't change on them while being returned or while processing
the information, so they must be written accordingly.

Discussed with:	ken, mav (in general)
MFC after:	1 week
Sponsored by:	Spectra Logic
This commit is contained in:
Will Andrews 2015-01-20 21:15:33 +00:00
parent 10a7450a2f
commit 636870ff01

View File

@ -93,6 +93,8 @@ struct xpt_task {
};
struct xpt_softc {
uint32_t xpt_generation;
/* number of high powered commands that can go through right now */
struct mtx xpt_highpower_lock;
STAILQ_HEAD(highpowerlist, cam_ed) highpowerq;
@ -151,6 +153,8 @@ static struct xpt_softc xsoftc;
SYSCTL_INT(_kern_cam, OID_AUTO, boot_delay, CTLFLAG_RDTUN,
&xsoftc.boot_delay, 0, "Bus registration wait time");
SYSCTL_UINT(_kern_cam, OID_AUTO, xpt_generation, CTLFLAG_RD,
&xsoftc.xpt_generation, 0, "CAM peripheral generation count");
struct cam_doneq {
struct mtx_padalign cam_doneq_mtx;
@ -976,6 +980,7 @@ xpt_add_periph(struct cam_periph *periph)
device->generation++;
SLIST_INSERT_HEAD(&device->periphs, periph, periph_links);
mtx_unlock(&device->target->bus->eb_mtx);
atomic_add_32(&xsoftc.xpt_generation, 1);
}
return (status);
@ -992,6 +997,7 @@ xpt_remove_periph(struct cam_periph *periph)
device->generation++;
SLIST_REMOVE(&device->periphs, periph, cam_periph, periph_links);
mtx_unlock(&device->target->bus->eb_mtx);
atomic_add_32(&xsoftc.xpt_generation, 1);
}
}