* We have to use get_memory_map_etc() instead of get_memory_map(), since

the scheduler thread doing that has no direct access to the
  destination team's address space.
* Improved some debug output.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@26601 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2008-07-24 04:11:03 +00:00
parent 6e60a6ac03
commit 9951d585b6
3 changed files with 28 additions and 20 deletions
@@ -331,14 +331,14 @@ DMAResource::TranslateNext(IORequest* request, IOOperation* operation)
uint32 segmentCount = 0; uint32 segmentCount = 0;
size_t partialBegin = offset & (fBlockSize - 1); size_t partialBegin = offset & (fBlockSize - 1);
TRACE(" offset %Ld, block size %lu -> partial: %lu\n", offset, fBlockSize, TRACE(" offset %Ld, remaining size: %lu, block size %lu -> partial: %lu\n",
partialBegin); offset, request->RemainingBytes(), fBlockSize, partialBegin);
if (buffer->IsVirtual()) { if (buffer->IsVirtual()) {
// Unless we need the bounce buffer anyway, we have to translate the // Unless we need the bounce buffer anyway, we have to translate the
// virtual addresses to physical addresses, so we can check the DMA // virtual addresses to physical addresses, so we can check the DMA
// restrictions. // restrictions.
TRACE(" buffer is virtual\n"); TRACE(" buffer is virtual %s\n", buffer->IsUser() ? "user" : "kernel");
// TODO: !partialOperation || totalLength >= fBlockSize // TODO: !partialOperation || totalLength >= fBlockSize
// TODO: Maybe enforce fBounceBufferSize >= 2 * fBlockSize. // TODO: Maybe enforce fBounceBufferSize >= 2 * fBlockSize.
if (true) { if (true) {
@@ -357,7 +357,9 @@ DMAResource::TranslateNext(IORequest* request, IOOperation* operation)
while (size > 0 && segmentCount while (size > 0 && segmentCount
< fRestrictions.max_segment_count) { < fRestrictions.max_segment_count) {
physical_entry entry; physical_entry entry;
get_memory_map((void*)base, size, &entry, 1); uint32 count = 1;
get_memory_map_etc(request->Team(), (void*)base, size,
&entry, &count);
vecs[segmentCount].iov_base = entry.address; vecs[segmentCount].iov_base = entry.address;
vecs[segmentCount].iov_len = entry.size; vecs[segmentCount].iov_len = entry.size;
@@ -681,7 +681,7 @@ IORequest::_CopyData(void* _buffer, off_t offset, size_t size, bool copyIn)
// If we can, we directly copy from/to the virtual buffer. The memory is // If we can, we directly copy from/to the virtual buffer. The memory is
// locked in this case. // locked in this case.
status_t (*copyFunction)(void*, void*, size_t, bool); status_t (*copyFunction)(void*, void*, size_t, team_id, bool);
if (fBuffer->IsPhysical()) { if (fBuffer->IsPhysical()) {
copyFunction = &IORequest::_CopyPhysical; copyFunction = &IORequest::_CopyPhysical;
} else { } else {
@@ -707,7 +707,7 @@ IORequest::_CopyData(void* _buffer, off_t offset, size_t size, bool copyIn)
while (size > 0) { while (size > 0) {
size_t toCopy = min_c(size, vecs[0].iov_len - vecOffset); size_t toCopy = min_c(size, vecs[0].iov_len - vecOffset);
status_t error = copyFunction(buffer, status_t error = copyFunction(buffer,
(uint8*)vecs[0].iov_base + vecOffset, toCopy, copyIn); (uint8*)vecs[0].iov_base + vecOffset, toCopy, fTeam, copyIn);
if (error != B_OK) if (error != B_OK)
return error; return error;
@@ -723,7 +723,7 @@ IORequest::_CopyData(void* _buffer, off_t offset, size_t size, bool copyIn)
/* static */ status_t /* static */ status_t
IORequest::_CopySimple(void* bounceBuffer, void* external, size_t size, IORequest::_CopySimple(void* bounceBuffer, void* external, size_t size,
bool copyIn) team_id team, bool copyIn)
{ {
TRACE(" IORequest::_CopySimple(%p, %p, %lu, %d)\n", bounceBuffer, external, TRACE(" IORequest::_CopySimple(%p, %p, %lu, %d)\n", bounceBuffer, external,
size, copyIn); size, copyIn);
@@ -737,7 +737,7 @@ IORequest::_CopySimple(void* bounceBuffer, void* external, size_t size,
/* static */ status_t /* static */ status_t
IORequest::_CopyPhysical(void* _bounceBuffer, void* _external, size_t size, IORequest::_CopyPhysical(void* _bounceBuffer, void* _external, size_t size,
bool copyIn) team_id team, bool copyIn)
{ {
uint8* bounceBuffer = (uint8*)_bounceBuffer; uint8* bounceBuffer = (uint8*)_bounceBuffer;
addr_t external = (addr_t)_external; addr_t external = (addr_t)_external;
@@ -749,7 +749,7 @@ IORequest::_CopyPhysical(void* _bounceBuffer, void* _external, size_t size,
return error; return error;
size_t toCopy = min_c(size, B_PAGE_SIZE); size_t toCopy = min_c(size, B_PAGE_SIZE);
_CopySimple(bounceBuffer, (void*)virtualAddress, toCopy, copyIn); _CopySimple(bounceBuffer, (void*)virtualAddress, toCopy, team, copyIn);
vm_put_physical_page(virtualAddress); vm_put_physical_page(virtualAddress);
@@ -764,24 +764,28 @@ IORequest::_CopyPhysical(void* _bounceBuffer, void* _external, size_t size,
/* static */ status_t /* static */ status_t
IORequest::_CopyUser(void* _bounceBuffer, void* _external, size_t size, IORequest::_CopyUser(void* _bounceBuffer, void* _external, size_t size,
bool copyIn) team_id team, bool copyIn)
{ {
uint8* bounceBuffer = (uint8*)_bounceBuffer; uint8* bounceBuffer = (uint8*)_bounceBuffer;
uint8* external = (uint8*)_external; uint8* external = (uint8*)_external;
while (size > 0) { while (size > 0) {
physical_entry entries[8]; static const int32 kEntryCount = 8;
int32 count = get_memory_map(external, size, entries, 8); physical_entry entries[kEntryCount];
if (count <= 0) {
uint32 count = kEntryCount;
status_t error = get_memory_map_etc(team, external, size, entries,
&count);
if (error != B_OK && error != B_BUFFER_OVERFLOW) {
panic("IORequest::_CopyUser(): Failed to get physical memory for " panic("IORequest::_CopyUser(): Failed to get physical memory for "
"user memory %p\n", external); "user memory %p\n", external);
return B_BAD_ADDRESS; return B_BAD_ADDRESS;
} }
for (int32 i = 0; i < count; i++) { for (uint32 i = 0; i < count; i++) {
const physical_entry& entry = entries[i]; const physical_entry& entry = entries[i];
status_t error = _CopyPhysical(bounceBuffer, entry.address, error = _CopyPhysical(bounceBuffer, entry.address,
entry.size, copyIn); entry.size, team, copyIn);
if (error != B_OK) if (error != B_OK)
return error; return error;
@@ -31,7 +31,7 @@ public:
bool IsVirtual() const { return !fPhysical; } bool IsVirtual() const { return !fPhysical; }
bool IsPhysical() const { return fPhysical; } bool IsPhysical() const { return fPhysical; }
bool IsUser() const { return !fUser; } bool IsUser() const { return fUser; }
void SetVecs(const iovec* vecs, uint32 count, void SetVecs(const iovec* vecs, uint32 count,
size_t length, uint32 flags); size_t length, uint32 flags);
@@ -193,6 +193,7 @@ struct IORequest : IORequestChunk, DoublyLinkedListLinkImpl<IORequest> {
bool IsWrite() const { return fIsWrite; } bool IsWrite() const { return fIsWrite; }
bool IsRead() const { return !fIsWrite; } bool IsRead() const { return !fIsWrite; }
team_id Team() const { return fTeam; }
IOBuffer* Buffer() const { return fBuffer; } IOBuffer* Buffer() const { return fBuffer; }
off_t Offset() const { return fOffset; } off_t Offset() const { return fOffset; }
@@ -215,11 +216,12 @@ private:
status_t _CopyData(void* buffer, off_t offset, status_t _CopyData(void* buffer, off_t offset,
size_t size, bool copyIn); size_t size, bool copyIn);
static status_t _CopySimple(void* bounceBuffer, void* external, static status_t _CopySimple(void* bounceBuffer, void* external,
size_t size, bool copyIn); size_t size, team_id team, bool copyIn);
static status_t _CopyPhysical(void* bounceBuffer, static status_t _CopyPhysical(void* bounceBuffer,
void* external, size_t size, bool copyIn); void* external, size_t size, team_id team,
bool copyIn);
static status_t _CopyUser(void* bounceBuffer, void* external, static status_t _CopyUser(void* bounceBuffer, void* external,
size_t size, bool copyIn); size_t size, team_id team, bool copyIn);
mutex fLock; mutex fLock;
IOBuffer* fBuffer; IOBuffer* fBuffer;