Thanks for the feedback. I'm answering some of your questions inline.

On 2018-03-06 06:09 PM, Dave Airlie wrote:
> On 7 March 2018 at 08:44, Felix Kuehling <> wrote:
>> Hi all,
>> Christian raised two potential issues in a recent KFD upstreaming code
>> review that are related to the KFD ioctl APIs:
>>  1. behaviour of -ERESTARTSYS
>>  2. transactional nature of KFD ioctl definitions, or lack thereof
>> I appreciate constructive feedback, but I also want to encourage an
>> open-minded rather than a dogmatic approach to API definitions. So let
>> me take all the skeletons out of my closet and get these APIs reviewed
>> in the appropriate forum before we commit to them upstream. See the end
>> of this email for reference.
>> The controversial part at this point is kfd_ioctl_map_memory_to_gpu. If
>> any of the other APIs raise concerns or questions, please ask.
>> Because of the HSA programming model, KFD memory management APIs are
>> synchronous. There is no pipelining. Command submission to GPUs through
>> user mode queues does not involve KFD. This means KFD doesn't know what
>> memory is used by the GPUs and when it's used. That means, when the
>> map_memory_to_gpu ioctl returns to user mode, all memory mapping
>> operations are complete and the memory can be used by the CPUs or GPUs
>> immediately.
> I've got a few opinions, but first up I still dislike user-mode queues
> and everything
> they entail. I still feel they are solving a Windows problem and not a
> Linux problem,
> and it would be nice if we had some Linux numbers on what they gain us over
> a dispatch ioctl, because they sure bring a lot of memory management issues.
> That said amdkfd is here.
> The first question you should ask (which you haven't asked here at all) is
> what should userspace do with the ioctl result.
>> HSA also uses a shared virtual memory model, so typically memory gets
>> mapped on multiple GPUs and CPUs at the same virtual address.
>> The point of contention seems to be the ability to map memory to
>> multiple GPUs in a single ioctl and the behaviour in failure cases. I'll
>> discuss two main failure cases:
>> 1: Failure after all mappings have been dispatched via SDMA, but a
>> signal interrupts the wait for completion and we return -ERESTARTSYS.
>> Documentation/kernel-hacking/hacking.rst only says "[...] you should be
>> prepared to process the restart, e.g. if you're in the middle of
>> manipulating some data structure." I think we do that by ensuring that
>> memory that's already mapped won't be mapped again. So the restart will
>> become a no-op and just end up waiting for all the previous mappings to
>> complete.
> -ERESTARTSYS at that late stage points to a badly synchronous API,
> I'd have said you should have two ioctls, one that returns a fence after
> starting the processes, and one that waits for the fence separately.
> The overhead of ioctls isn't your enemy until you've measured it and
> proven it's a problem.
>> Christian has a stricter requirement, and I'd like to know where that
>> comes from: "An interrupted IOCTL should never have a visible effect."
> Christian might be taking things a bit further but synchronous gpu access
> APIs are bad, but I don't think undoing a bunch of work is a good plan either
> just because you got ERESTARTSYS. If you get ERESTARTSYS can you
> handle it, if I've fired off 5 SDMAs and wait for them will I fire off 5 more?
> will I wait for the original SDMAs if I reenter?

It will wait for the original SDMAs to complete.

>> 2: Failure to map on some but not all GPUs. This comes down to the
>> question, do all ioctl APIs or system calls in general need to be
>> transactional? As a counter example I'd give incomplete read or write
>> system calls that return how much was actually read or written. Our
>> current implementation of map_memory_to_gpu doesn't do this, but it
>> could be modified to return to user mode how many of the mappings, or
>> which mappings specifically failed or succeeded.
> What should userspace do? if it only get mappings on 3 of the gpus instead
> of say 4? Is there a sane resolution other than calling the ioctl again with
> the single GPU? Would it drop the GPU from the working set from that point on?
> Need more info to do what can come out of the API doing incomplete
> operations.

There are two typical use cases where this function is used.

 1. During allocation
 2. Changing access to an existing buffer

There is no retry logic in either case. And given the likely failure
conditions, a retry doesn't really make much sense.

I think the most likely failure I've seen is a failure to validate the
BO under heavy memory pressure. This will affect the first GPU trying to
map the memory. Once it's mapped on one GPU, subsequent GPUs don't need
to validate it again, so that's less likely to fail. Maybe if we're
running out of space for the SDMA command buffers. If you're under that
much memory pressure, it's unlikely that a retry would help. Or SDMA
could be hanging, leading to a timeout. Again, a retry won't help. You'd
need a GPU reset at that point.

So I think the expected response from user mode is that it will fail the
operation and not retry. If it happens during allocation, the BO will be
released. The application will probably crash or fail gracefully,
depending on how well it's written. A really badly written application
may keep going with a NULL pointer and get a GPUVM fault later on that
will ultimately terminate the application.

>> The alternative would be to break multi-GPU mappings, and the final wait
>> for completion, into multiple ioctl calls. That would result in
>> additional system call overhead. I'd argue that the end result is the
>> same for user mode, so I don't see why I'd use multiple ioctls over a
>> single one.
> Again stop worrying about ioctl overhead, this isn't Windows. If you
> can show the overhead as being a problem then address it, but I
> think it's premature worrying about it at this stage.

I'd like syscall overhead to be small. But with recent kernel page table
isolation, NUMA systems and lots of GPUs, I think this may not be
negligible. For example we're working with some Intel NUMA systems and 8
GPUs for HPC or deep learning applications. I'll be measuring the
overhead on such systems and get back with results in a few days. I want
to have an API that can scale to such applications.


> Dave.

amd-gfx mailing list

Reply via email to