qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH 1/5] Add target memory mapping API


From: Anthony Liguori
Subject: Re: [Qemu-devel] [PATCH 1/5] Add target memory mapping API
Date: Mon, 19 Jan 2009 13:23:57 -0600
User-agent: Thunderbird 2.0.0.19 (X11/20090105)

Ian Jackson wrote:
Anthony Liguori writes ("Re: [Qemu-devel] [PATCH 1/5] Add target memory mapping 
API"):
The packet IO API is a bit different.  It looks like:

The purpose here is to be able to make only one system call to the
host kernel in order to do an operation which involves a scatter
gather list in guest physical memory (as provided by the guest to eg
an emulated DMA controller) ?

And the idea is to try to map as much of that contiguously as
possible so that only one system call need be made ?

No, it's not an issue of performance, it's an issue of correctness. A single readv/writev system call to a tap file descriptor corresponds to a single packet. You cannot split a packet into multiple read/write operations to tap IIUC.

Are there supposed to be fast-path devices where we absolutely must
make the host system call for the whole transfer in one go, in one
contiguous memory region ?

It's a matter of correctness. Packet protocols (datagram protocols if you will) must preserve message boundaries.

So this is why I prefer the map() API, as it accommodates two distinct users in a way that the callback API wouldn't. We can formalize these idioms into an API, of course.

I don't think there is any fundamental difference between a callback
API and a polling API; you can implement whatever semantics you like
with either.

But callbacks are needed in at least some cases because of the way
that the bounce buffer may need to be reserved/released.  That means
all of the callers have to deal with callbacks anyway.

So it makes sense to make that the only code path.  That way callers
only need to be written once.

If you use callbacks, consider the following:

Scenario 1 (no callbacks)

1) Attempt to map all data in packet
2) Failure occurs b/c bounce buffer is too small to contain packet
3) We can't do zero-copy IO here, so fall back to a copy to a device supplied buffer
4) Transmit full packet

Scenario 2 (callbacks)

1) Register callback and begin data mapping
2) Succeed in mapping first part of packet and 1 page of bounced buffer
3) Bounce buffer is exhausted, callback will not be invoked until the next unmap
4) Deadlock

You could add some sort of call to determine if the bounce memory is exhausted and try to take some corrective action in #2 but it gets ugly.

So as I said earlier, I think the callback model makes sense when you have streaming data (where there are no packet boundaries). I think it's pretty difficult to avoid deadlocking though with callbacks in a packet model (where boundaries must be preserved).

Regards,

Anthony Liguori

BTW, to support this model, we have to reserve at least one bounce buffer for cpu_physical_memory_rw.

Yes.

Ian.







reply via email to

[Prev in Thread] Current Thread [Next in Thread]