scatter-gather list in Linux kernel device driver

Tejas Chopra picture Tejas Chopra · Sep 30, 2013 · Viewed 9.1k times · Source

I am working on a device driver that has access to a scatter-gather list (sg) element. I am able to extract the data out of it and store it in an allocated buffer using sg_copy_to_buffer. Now, my idea is to create a new scatterlist and copy from this buffer into the new scatterlist I create (ofcourse this is done later) and return this new scatterlist back to the kernel. (This is for performance metrics, etc.) I tried searching online for documentation to use scatterlist, etc. but to no avail. What I typically am doing:

char *buffer = kmalloc (***);
struct scatterlist *sglist = kmalloc (sizeof (struct scatterlist)...);
sg_init_one(sglist, buffer, BUFFER_SIZE);

sg_copy_to_buffer (inp_sglist, inp_sglist_len, buffer);

*** Later ***
sg_copy_from_buffer (sglist, 1, buffer);

Is there a good documentation to help me map my scatterlist to a virtual buffer? I tried looking at http://lwn.net/Articles/256368/ http://www.linuxjournal.com/article/7104 etc.

Any help or pointers would be appreciated!

Answer

Mark Sherred picture Mark Sherred · Oct 2, 2013

Typically the user allocates a buffer in their virtual memory and then calls the device driver. When the user issues a write, you get the sglist for the buffer with the write data and use it in the sg_copy_to_buffer(). When the user issues a read, you get the sglist for the read data buffer and use it in the sg_copy_from_buffer().

The call to get the sglist from the I/O request is described in the article. It is a good article, but almost 10 years old. Many x86 systems now have an IOMMU to support hardware virtualization.

Usually device drivers use the sglist to generate a list of device I/O operations, one for each disjoint block of data in a sglist entry, not to copy the data into a local buffer.