3

在我听说内核 3.8 linux 添加了多队列功能以使用标志 IFF_MULTI_QUEUE 调整抽头设备后,我将内核升级到 3.10 并将其标头放在 /usr/src 然后我更改了我的 c 代码以有一个线程来打开一个新队列每次需要文件描述符。但线程只能打开 8 个队列(使用我早于 3.8 的内核,它根本无法打开队列),然后我从 ioctl 中得到这个“参数太长”错误

ioctl(fd, TUNSETIFF, (void *)&ifr)

然后我编写了另一个程序来测试可以在我的 ubuntu 12.10 linux 盒子中打开多少队列 fd

uname -r
3.10.0-031000-generic 

内核版本在一个更简单的程序中。

//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 %d\n",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 error\n");
            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;
}

事实证明,这也仅限于 8 个。这是输出:

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

我在另一个 linux 机器上对其进行了测试,它具有相同的输出。那么从内核中的 tun 设备打开超过 8 个队列是否有限制?如果是这样,如何解决?请帮帮我

4

2 回答 2

3

如果你想从一个 tun 接口获取超过 8 个队列文件描述符,你可以将你的 linux 内核升级到 4.0+,它支持 256 个队列。

于 2015-09-23T09:05:30.467 回答
1

从 tun 驱动程序中,我们可以看到以下内容

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_QUEUESlinux/netdevice.h中定义为:

2187 #define DEFAULT_MAX_NUM_RSS_QUEUES      (8)

因此,8 是默认值。

于 2013-09-10T13:59:10.493 回答