Skip to content

linux_set_if_mac: fail to set kni0's MAC address: Timer expired #503

Open
@hulinfan

Description

@hulinfan

【现象描述】
使用dpdk 18.11的dpvs,在网口初始化流程netif_port_init中,网口初始化完成后添加kni_dev,并设置kni的MAC地址使其和物理口的一致。实际发现设置kni的MAC地址的时候总是超时,提示 "linux_set_if_mac: fail to set kni0's MAC address: Timer expired"。

【原因分析】
设置MAC地址的linux_set_if_mac是通过ioctl(..., SIOCSIFHWADDR, ...)实现的,系统调用最终会执行kni内核模块的ndo_set_mac_address,也即kni_net_set_mac,其中的kni_net_process_request,会把MAC地址的变动作为request放到kni fifo队列,并等待用户态从kni fifo队列取走request,用户态处理完毕回一个reply到kni fifo队列,此后kni内核模块的等待队列被唤醒,整个流程走完:

ioctl --> ndo_set_mac_address --> kni_net_set_mac --> kni_net_process_request --> kni_fifo_put(req) --> wait_event_interruptible_timeout -> kni_fifo_get(resp)  

问题出现在网口初始化的时候用户态没有执行kni_process_on_master响应kni内核模块的请求,导致wait event超时,ioctl返回'Timer expired'。事实上kni_process_on_master是在所有初始化完成后master线程的while循环里执行的,因此在网口初始化流程里企图改变kni口的一些信息如MAC地址、MTU等都会发生超时。以下回调凡是用了kni_net_process_request都会有这个问题:

static const struct net_device_ops kni_net_netdev_ops = {
	.ndo_open = kni_net_open,
	.ndo_stop = kni_net_release,
	.ndo_set_config = kni_net_config,
	.ndo_change_rx_flags = kni_net_set_promiscusity,
	.ndo_start_xmit = kni_net_tx,
	.ndo_change_mtu = kni_net_change_mtu,
	.ndo_do_ioctl = kni_net_ioctl,
	.ndo_set_rx_mode = kni_net_set_rx_mode,
	.ndo_get_stats = kni_net_stats,
	.ndo_tx_timeout = kni_net_tx_timeout,
	.ndo_set_mac_address = kni_net_set_mac,
#ifdef HAVE_CHANGE_CARRIER_CB
	.ndo_change_carrier = kni_net_change_carrier,
#endif
};

【影响范围】
影响程序启动的时间,每个port初始化都会3秒超时,程序启动将会拖长 3 * nr_ports 秒的时间。
不影响MAC地址的设置,kni口MAC地址仍能配置成功。

【为什么dpdk 17.11没有这个问题】
dpdk 17.11 的回调 kni_net_set_mac没有wait event的操作:

static int
kni_net_set_mac(struct net_device *netdev, void *p)
{
	struct sockaddr *addr = p;

	if (!is_valid_ether_addr((unsigned char *)(addr->sa_data)))
		return -EADDRNOTAVAIL;
	memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
	return 0;
}

【解决办法】
这个问题似乎是无解的,除非使用异步的方式设置MAC地址。

Metadata

Metadata

Assignees

Labels

issue/to-solveissues await answers tobe solved

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions