diff --git a/src/system/kernel/device_manager/IOScheduler.cpp b/src/system/kernel/device_manager/IOScheduler.cpp index b6f2a9f5ee..030ead6599 100644 --- a/src/system/kernel/device_manager/IOScheduler.cpp +++ b/src/system/kernel/device_manager/IOScheduler.cpp @@ -108,7 +108,8 @@ IOScheduler::ScheduleRequest(IORequest* request) // lock memory (via another thread or a dedicated call). if (buffer->IsVirtual()) { - status_t status = buffer->LockMemory(request->IsWrite()); + status_t status = buffer->LockMemory(B_CURRENT_TEAM, + request->IsWrite()); if (status != B_OK) return status; } diff --git a/src/system/kernel/device_manager/io_requests.cpp b/src/system/kernel/device_manager/io_requests.cpp index 4f4064b7cf..9ca6dcc4a3 100644 --- a/src/system/kernel/device_manager/io_requests.cpp +++ b/src/system/kernel/device_manager/io_requests.cpp @@ -76,13 +76,13 @@ IOBuffer::SetVecs(const iovec* vecs, uint32 count, size_t length, uint32 flags) status_t -IOBuffer::LockMemory(bool isWrite) +IOBuffer::LockMemory(team_id team, bool isWrite) { for (uint32 i = 0; i < fVecCount; i++) { - status_t status = lock_memory(fVecs[i].iov_base, fVecs[i].iov_len, - isWrite ? 0 : B_READ_DEVICE); + status_t status = lock_memory_etc(team, fVecs[i].iov_base, + fVecs[i].iov_len, isWrite ? 0 : B_READ_DEVICE); if (status != B_OK) { - _UnlockMemory(i, isWrite); + _UnlockMemory(team, i, isWrite); return status; } } @@ -92,19 +92,19 @@ IOBuffer::LockMemory(bool isWrite) void -IOBuffer::_UnlockMemory(size_t count, bool isWrite) +IOBuffer::_UnlockMemory(team_id team, size_t count, bool isWrite) { for (uint32 i = 0; i < count; i++) { - unlock_memory(fVecs[i].iov_base, fVecs[i].iov_len, + unlock_memory_etc(team, fVecs[i].iov_base, fVecs[i].iov_len, isWrite ? 0 : B_READ_DEVICE); } } void -IOBuffer::UnlockMemory(bool isWrite) +IOBuffer::UnlockMemory(team_id team, bool isWrite) { - _UnlockMemory(fVecCount, isWrite); + _UnlockMemory(team, fVecCount, isWrite); } @@ -595,6 +595,12 @@ IORequest::ChunkFinished(IORequestChunk* chunk, status_t status, bool remove) if (fStatus == 1) fStatus = B_OK; + // unlock the memory + // TODO: That should only happen for the request that locked the memory, + // not for its ancestors. + if (fBuffer->IsVirtual()) + fBuffer->UnlockMemory(fTeam, fIsWrite); + // Cache the callbacks before we unblock waiters and unlock. Any of the // following could delete this request, so we don't want to touch it once // we have started telling others that it is done. diff --git a/src/system/kernel/device_manager/io_requests.h b/src/system/kernel/device_manager/io_requests.h index b12968aee4..c45158b5b0 100644 --- a/src/system/kernel/device_manager/io_requests.h +++ b/src/system/kernel/device_manager/io_requests.h @@ -49,13 +49,14 @@ public: size_t VecCount() const { return fVecCount; } size_t Capacity() const { return fCapacity; } - status_t LockMemory(bool isWrite); - void UnlockMemory(bool isWrite); + status_t LockMemory(team_id team, bool isWrite); + void UnlockMemory(team_id team, bool isWrite); private: ~IOBuffer(); // not implemented - void _UnlockMemory(size_t count, bool isWrite); + void _UnlockMemory(team_id team, size_t count, + bool isWrite); bool fUser; bool fPhysical;