sbefifo userspace api

Brad Bishop bradleyb at fuzziesquirrel.com
Sun Feb 26 01:46:27 AEDT 2017


> Thanks for correcting me :-) Also, the kernel driver should return error if a read(fd) is done without a preceding write(fd).
> This error must be returned by kernel driver before touching the fifo itself.

Again, it is the job of the driver to make sure that the fifo is ‘touched’ in the correct way.

The read system call will likely never touch the fifo in any case.

Consider this sample implementation of the read system call:

size_t sbefifo_read(fd, buf)
{
    struct *sbefifo sbe = dev_from_fd(fd);

    if(response_received(sbe->responses[fd])) {
        copy_user(sbe->responses[fd]);
        return len(sbe->data[fd]);
    }

    wait_interuptible(sbe->queues[fd]);
    copy_user(sbe->data[fd]);
    return len(sbe->data[fd]);
}

If a single threaded application calls this function without doing a write first,
that is a bug in the application, because it has just deadlocked itself.  This function
is never going to return from the system call because the wait event associated
with this fd is never going to occur.

It isn’t appropriate to make this an error, because that would prevent something
like a multithreaded application from doing a read in one thread, and then later
doing a write from another thread, which, as far as the kernel is concerned, is
a perfect valid thing for user space to do.

> One more use-case to cover --- If a read(fd) is done with a not-so-large-enough buffer, then kernel driver should flush the downstream fifo until it is empty and return buffer-too-small error to the caller. User cannot allocate a bigger buffer and retry read(fd) as it will end up in two consecutive reads without a write.

It won’t though.  A read system call != reading from the fifo.  A read system
call means give me back the data that came out of the fifo after I did a write.

> 
> -Venkatesh


More information about the openbmc mailing list