usb_disk: Lock memory before acquiring device locks.
Otherwise, if we are locking memory that's mapped from this same usb_disk device, we'll cause a double lock. Should fix #19715. But really, we should probably be using an IOScheduler here, so the next commit will implement that. Change-Id: Icd62955338ef66444ec6a14e0310f60061456d8f Reviewed-on: https://review.haiku-os.org/c/haiku/+/9610 Reviewed-by: waddlesplash <[email protected]> Tested-by: Commit checker robot <[email protected]>
This commit is contained in:
committed by
waddlesplash
parent
fb6c279a24
commit
505b9a5c31
@@ -1817,19 +1817,12 @@ usb_disk_ioctl(void *cookie, uint32 op, void *buffer, size_t length)
|
|||||||
static status_t
|
static status_t
|
||||||
usb_disk_bounced_io(device_lun *lun, io_request *request)
|
usb_disk_bounced_io(device_lun *lun, io_request *request)
|
||||||
{
|
{
|
||||||
|
ASSERT(request->Buffer()->IsPhysical() || request->Buffer()->IsMemoryLocked());
|
||||||
|
|
||||||
DMAResource* dmaResource = get_dma_resource(lun->device, lun->block_size);
|
DMAResource* dmaResource = get_dma_resource(lun->device, lun->block_size);
|
||||||
if (dmaResource == NULL)
|
if (dmaResource == NULL)
|
||||||
return B_NO_INIT;
|
return B_NO_INIT;
|
||||||
|
|
||||||
if (!request->Buffer()->IsPhysical()) {
|
|
||||||
status_t status = request->Buffer()->LockMemory(request->TeamID(), request->IsWrite());
|
|
||||||
if (status != B_OK) {
|
|
||||||
TRACE_ALWAYS("failed to lock memory: %s\n", strerror(status));
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
// SetStatusAndNotify() takes care of unlocking memory if necessary.
|
|
||||||
}
|
|
||||||
|
|
||||||
status_t status = B_OK;
|
status_t status = B_OK;
|
||||||
while (request->RemainingBytes() > 0) {
|
while (request->RemainingBytes() > 0) {
|
||||||
IOOperation operation;
|
IOOperation operation;
|
||||||
@@ -1919,6 +1912,17 @@ usb_disk_io(void *cookie, io_request *request)
|
|||||||
device_lun *lun = (device_lun *)cookie;
|
device_lun *lun = (device_lun *)cookie;
|
||||||
disk_device *device = lun->device;
|
disk_device *device = lun->device;
|
||||||
|
|
||||||
|
const bool needsBounce = usb_disk_needs_bounce(lun, request);
|
||||||
|
|
||||||
|
if (needsBounce && !request->Buffer()->IsPhysical()) {
|
||||||
|
status_t status = request->Buffer()->LockMemory(request->TeamID(), request->IsWrite());
|
||||||
|
if (status != B_OK) {
|
||||||
|
TRACE_ALWAYS("failed to lock memory: %s\n", strerror(status));
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
// SetStatusAndNotify() takes care of unlocking memory if necessary.
|
||||||
|
}
|
||||||
|
|
||||||
RecursiveLocker ioLocker(device->io_lock);
|
RecursiveLocker ioLocker(device->io_lock);
|
||||||
MutexLocker deviceLocker(device->lock);
|
MutexLocker deviceLocker(device->lock);
|
||||||
|
|
||||||
@@ -1926,7 +1930,7 @@ usb_disk_io(void *cookie, io_request *request)
|
|||||||
return B_DEV_NOT_READY;
|
return B_DEV_NOT_READY;
|
||||||
|
|
||||||
status_t status;
|
status_t status;
|
||||||
if (!usb_disk_needs_bounce(lun, request)) {
|
if (!needsBounce) {
|
||||||
status = usb_disk_direct_io(lun, request);
|
status = usb_disk_direct_io(lun, request);
|
||||||
} else {
|
} else {
|
||||||
status = usb_disk_bounced_io(lun, request);
|
status = usb_disk_bounced_io(lun, request);
|
||||||
|
|||||||
Reference in New Issue
Block a user