After I heared that after kernel 3.8 linux added multi queue ability to tun tap device with flag IFF_MULTI_QUEUE, I upgraded my kernel to 3.10 and have its header in /usr/src then I altered my c code to have a thread to open a new queue file descriptor each time neaded. but the thread could just open 8 queue (with my earlier than 3.8 kernel, it could not open queue at all) and after that I get this “Arguments too long” error from ioctl in
ioctl(fd, TUNSETIFF, (void *)&ifr)
then I wrote another program to test how much queue fd can be opend in my ubuntu 12.10 linux box with this
uname -r 3.10.0-031000-generic
kernel version in a much simpler program.
//essential #include <net/if.h> #include <linux/if_tun.h> #include <sys/ioctl.h> #include <fcntl.h> #include <arpa/inet.h> // #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/stat.h> #include <sys/types.h> #include <sys/socket.h> #include <sys/select.h> #include <sys/time.h> #include <errno.h> #include <stdarg.h> #include <netdb.h> #define IFF_MULTI_QUEUE 0x0100 int tun_alloc_mq(char *dev, int queues, int *fds) { struct ifreq ifr; int fd, err=-1, i; char *clonedev = "/dev/net/tun"; if (!dev){ printf("dev"); return -1; } memset(&ifr, 0, sizeof(ifr)); ifr.ifr_flags = IFF_TAP | IFF_NO_PI | IFF_MULTI_QUEUE; strcpy(ifr.ifr_name, dev); int error=0; for (i = 0; i < queues; i++) { printf("loop %dn",i); if( (fd = open(clonedev , O_RDWR)) < 0 ) { perror("Opening /dev/net/tun"); error=1; break; } if(ioctl(fd, TUNSETIFF, (void *)&ifr) < 0 ) { printf("first errorn"); error=1; close(fd); break; } } if(error==1) return -1; return 0; } int main(int argc, char *argv[]) { int* fdsx; if(tun_alloc_mq("testmqtun0",20,fdsx)<0) { perror("tun"); exit(1); } return 0; }
and it turns out this is limited to 8 too. here is the output:
loop 0 loop 1 loop 2 loop 3 loop 4 loop 5 loop 6 loop 7 loop 8 first error tun: Argument list too long
I tested it on another linux box and it had the same output. So is there a limit to opening more than 8 queue from a tun device in kernel? if so, how to fix that? please help me with that
Advertisement
Answer
From the tun driver we can see the following:
112 /* DEFAULT_MAX_NUM_RSS_QUEUES were choosed to let the rx/tx queues allocated for 113 * the netdevice to be fit in one page. So we can make sure the success of 114 * memory allocation. TODO: increase the limit. */ 115 #define MAX_TAP_QUEUES DEFAULT_MAX_NUM_RSS_QUEUES [...] 500 static int tun_attach(struct tun_struct *tun, struct file *file) 501 { [...] 518 if (!tfile->detached && 519 tun->numqueues + tun->numdisabled == MAX_TAP_QUEUES) 520 goto out; [...]
DEFAULT_MAX_NUM_RSS_QUEUES
is defined at linux/netdevice.h as:
2187 #define DEFAULT_MAX_NUM_RSS_QUEUES (8)
So, 8 is the default value.