Searched hist:"33 a38f7453a5c2b4afca8729c081bda79afa2a44" (Results 1 – 2 of 2) sorted by relevance
/freebsd/sys/cam/ |
H A D | cam_periph.c | diff 33a38f7453a5c2b4afca8729c081bda79afa2a44 Sat Dec 08 00:48:54 CET 2012 Kenneth D. Merry <ken@FreeBSD.org> Fix a panic during CAM EDT traversal.
The problem was a race condition between the EDT traversal used by things like 'camcontrol devlist', and CAM peripheral driver removal.
The EDT traversal code holds the CAM topology lock, and wants to show devices that have been invalidated. It acquires a reference to the peripheral to make sure the peripheral it is examining doesn't go away.
However, because the peripheral removal code in camperiphfree() drops the CAM topology lock to call the peripheral's destructor routine, we can run into a situation where the EDT traversal increments the peripheral reference count after free process is already in progress. At that point, the reference count is ignored, because it was 0 when we started the process.
Fix this race by setting a flag, CAM_PERIPH_FREE, that I previously added and checked in xptperiphtraverse() and xptpdperiphtravsere(), but failed to use. If the EDT traversal code sees that flag, it will know that the peripheral free process has already started, and that it should not access that peripheral.
Also, fix an inconsistency in the locking between xptpdperiphtraverse() and xptperiphtraverse(). They now both hold the CAM topology lock while calling the peripheral traversal function.
cam_xpt.c: Change xptperiphtraverse() to hold the CAM topology lock across calls to the traversal function.
Take out the comment in xptpdperiphtraverse() that referenced the locking inconsistency.
cam_periph.c: Set the CAM_PERIPH_FREE flag when we are in the process of freeing a peripheral driver.
Sponsored by: Spectra Logic Corporation MFC after: 1 week
|
H A D | cam_xpt.c | diff 33a38f7453a5c2b4afca8729c081bda79afa2a44 Sat Dec 08 00:48:54 CET 2012 Kenneth D. Merry <ken@FreeBSD.org> Fix a panic during CAM EDT traversal.
The problem was a race condition between the EDT traversal used by things like 'camcontrol devlist', and CAM peripheral driver removal.
The EDT traversal code holds the CAM topology lock, and wants to show devices that have been invalidated. It acquires a reference to the peripheral to make sure the peripheral it is examining doesn't go away.
However, because the peripheral removal code in camperiphfree() drops the CAM topology lock to call the peripheral's destructor routine, we can run into a situation where the EDT traversal increments the peripheral reference count after free process is already in progress. At that point, the reference count is ignored, because it was 0 when we started the process.
Fix this race by setting a flag, CAM_PERIPH_FREE, that I previously added and checked in xptperiphtraverse() and xptpdperiphtravsere(), but failed to use. If the EDT traversal code sees that flag, it will know that the peripheral free process has already started, and that it should not access that peripheral.
Also, fix an inconsistency in the locking between xptpdperiphtraverse() and xptperiphtraverse(). They now both hold the CAM topology lock while calling the peripheral traversal function.
cam_xpt.c: Change xptperiphtraverse() to hold the CAM topology lock across calls to the traversal function.
Take out the comment in xptpdperiphtraverse() that referenced the locking inconsistency.
cam_periph.c: Set the CAM_PERIPH_FREE flag when we are in the process of freeing a peripheral driver.
Sponsored by: Spectra Logic Corporation MFC after: 1 week
|