Answers to: Avoid copying of data between user and kernel space and vice-versahttp://linuxexchange.org/questions/204/avoid-copying-of-data-between-user-and-kernel-space-and-vice-versa<p>Hello, I am developing a active messaging protocol for parallel computation that replaces TCP/IP. My goal is to decrease the latency of a packet. Since the environment is a LAN, i can replace TCP/IP with simpler protocol to reduce the packet latency. I am not writing any device driver and i am just trying to replace the TCP/IP stack with something simpler. Now I wanted to avoid copying of a packet's data from user space to kernel space and vice-versa. I heard of the mmap(). Is it the best way to do this? If yes, it will be nice if you can give links to some examples. I am a linux newbie and i really appreciate your help.. Thank you...</p> <p>Thanks, Bala</p>enTue, 14 Jun 2011 11:44:29 -0400Comment by rfelsburg on bala1486's questionhttp://linuxexchange.org/questions/204/avoid-copying-of-data-between-user-and-kernel-space-and-vice-versa#2607<p>Please accept an answer, or provide more details on what you're looking for.</p>rfelsburgTue, 14 Jun 2011 11:44:29 -0400http://linuxexchange.org/questions/204/avoid-copying-of-data-between-user-and-kernel-space-and-vice-versa#2607Answer by Jubhttp://linuxexchange.org/questions/204/avoid-copying-of-data-between-user-and-kernel-space-and-vice-versa/235<p>Here's a working example for writing a file through mmap():</p> <pre><code>#include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; #include &lt;sys/types.h&gt; #include &lt;sys/stat.h&gt; #include &lt;unistd.h&gt; #include &lt;fcntl.h&gt; #include &lt;sys/mman.h&gt; #define FILEPATH "/tmp/mmapped.bin" #define NUMINTS (1000) #define FILESIZE (NUMINTS * sizeof(int)) int main(int argc, char *argv[]) { int i; int fd; int result; int *map; /* mmapped array of int's */ /* Open a file for writing. * - Creating the file if it doesn't exist. * - Truncating it to 0 size if it already exists. (not really needed) * * Note: "O_WRONLY" mode is not sufficient when mmaping. */ fd = open(FILEPATH, O_RDWR | O_CREAT | O_TRUNC, (mode_t)0600); if (fd == -1) { perror("Error opening file for writing"); exit(EXIT_FAILURE); } /* Stretch the file size to the size of the (mmapped) array of ints */ result = lseek(fd, FILESIZE-1, SEEK_SET); if (result == -1) { close(fd); perror("Error calling lseek() to 'stretch' the file"); exit(EXIT_FAILURE); } /* Something needs to be written at the end of the file to * have the file actually have the new size. * Just writing an empty string at the current file position will do. * * Note: * - The current position in the file is at the end of the stretched * file due to the call to lseek(). * - An empty string is actually a single '\0' character, so a zero-byte * will be written at the last byte of the file. */ result = write(fd, "", 1); if (result != 1) { close(fd); perror("Error writing last byte of the file"); exit(EXIT_FAILURE); } /* Now the file is ready to be mmapped. */ map = mmap(0, FILESIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); if (map == MAP_FAILED) { close(fd); perror("Error mmapping the file"); exit(EXIT_FAILURE); } /* Now write int's to the file as if it were memory (an array of ints). */ for (i = 1; i &lt;=NUMINTS; ++i) { map[i] = 2 * i; } /* Don't forget to free the mmapped memory */ if (munmap(map, FILESIZE) == -1) { perror("Error un-mmapping the file"); /* Decide here whether to close(fd) and exit() or not. Depends... */ } /* Un-mmaping doesn't close the file, so we still need to do that. */ close(fd); return 0; } </code></pre> <p>Reading the file created by the example above, is simpler as we don't need to create a file and "stretch" it to the mmapped size. So just remove that part, and open the file for reading only, and remove the PROT_WRITE flag from the mmap call.</p> <pre><code>#include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; #include &lt;sys/types.h&gt; #include &lt;sys/stat.h&gt; #include &lt;unistd.h&gt; #include &lt;fcntl.h&gt; #include &lt;sys/mman.h&gt; #define FILEPATH "/tmp/mmapped.bin" #define NUMINTS (1000) #define FILESIZE (NUMINTS * sizeof(int)) int main(int argc, char *argv[]) { int i; int fd; int *map; /* mmapped array of int's */ fd = open(FILEPATH, O_RDONLY); if (fd == -1) { perror("Error opening file for reading"); exit(EXIT_FAILURE); } map = mmap(0, FILESIZE, PROT_READ, MAP_SHARED, fd, 0); if (map == MAP_FAILED) { close(fd); perror("Error mmapping the file"); exit(EXIT_FAILURE); } /* Read the file int-by-int from the mmap */ for (i = 1; i &lt;=NUMINTS; ++i) { printf("%d: %d\n", i, map[i]); } if (munmap(map, FILESIZE) == -1) { perror("Error un-mmapping the file"); } close(fd); return 0; } </code></pre> <p>Hope this helps</p>JubTue, 04 May 2010 03:12:23 -0400http://linuxexchange.org/questions/204/avoid-copying-of-data-between-user-and-kernel-space-and-vice-versa/235