[35088.250898] Call Trace:[35088.255869] [<8101883c>] show_stack+0x54/0x88[35088.264678] [<811e3dfc>] dump_stack+0x94/0xcc[35088.273469] [<810b0dc4>] warn_alloc_failed+0xf8/0x11c[35088.283646] [<810b3780>] __alloc_pages_nodemask+0x750/0x84c[35088.294884] [<810218d0>] mips_dma_alloc_coherent+0x168/0x20c[35088.306291] [<812b0738>] mtk_open+0x4d8/0x55c[35088.315069] [<812f9c0c>] __dev_open+0xd4/0x154[35088.324036] [<812f9f3c>] __dev_change_flags+0xc0/0x17c[35088.334373] [<812fa020>] dev_change_flags+0x28/0x70[35088.344200] [<81310e10>] dev_ifsioc+0xf8/0x33c[35088.353155] [<81311528>] dev_ioctl+0x4d4/0x5e4[35088.362117] [<810fd580>] do_vfs_ioctl+0x5d4/0x63c[35088.371590] [<810fd638>] SyS_ioctl+0x50/0x94[35088.380208] [<810078d8>] syscall_common+0x30/0x54
问题原因
首先抛出问题原因:
这个宕机,是由于ifconfig up过程中,没有能够申请到连续的内存导致的
ifconfig的调用过程
ifconig up和ifconfig down调用的函数如下
static int set_if_up(char *ifname, short flags){return set_if_flags(ifname ,flags | IFF_UP);}static int set_if_down(char *ifname, short flags){return set_if_flags(ifname ,flags & ~IFF_UP);}
其实up和down都是执行了set_if_flags
static int set_if_flags(char *ifname, short flags){struct ifreq ifr;int res = 0;ifr.ifr_flags = flags;strncpy(ifr.ifr_name, ifname, IFNAMSIZ); //ifr.ifr_name="eth0"res = ioctl(skfd, SIOCSIFFLAGS, &ifr); //通过ioctl()向内核socket传递命令SIOCSIFFLAGS和ifr变量if (res < 0) {saved_errno = errno;v_print("Interface '%s': Error: SIOCSIFFLAGS failed: %s\n",ifname, strerror(saved_errno));} else {v_print("Interface '%s': flags set to %04X.\n", ifname, flags);}return res;}
SIOCSIFFLAGS是干嘛的?
int dev_ioctl(struct net *net, unsigned int cmd, void __user *arg){struct ifreq ifr;int ret;char *colon;//… …switch (cmd) {//… …case SIOCSIFFLAGS: //设置标志,比如ifconfig up/downcase SIOCSIFMETRIC:case SIOCSIFMTU: //设置MUT长度case SIOCSIFHWADDR: //设置mac物理地址//… …dev_load(net, ifr.ifr_name); //通过ifr.ifr_name(eth0)名字来加载网卡rtnl_lock(); //对net_device进行加锁,避免与运行冲突ret = dev_ifsioc(net, &ifr, cmd); //最终调用该函数rtnl_unlock();return ret;}
dev_ioctl会调用dev_ifsioc->dev_change_flags->dev_chang_flags->然后根据IFF_UP标志位,判断调用dev_open还是__dev_close;
现在面临的问题:
[35088.250898] Call Trace:[35088.255869] [<8101883c>] show_stack+0x54/0x88[35088.264678] [<811e3dfc>] dump_stack+0x94/0xcc[35088.273469] [<810b0dc4>] warn_alloc_failed+0xf8/0x11c[35088.283646] [<810b3780>] __alloc_pages_nodemask+0x750/0x84c[35088.294884] [<810218d0>] mips_dma_alloc_coherent+0x168/0x20c[35088.306291] [<812b0738>] mtk_open+0x4d8/0x55c[35088.315069] [<812f9c0c>] __dev_open+0xd4/0x154[35088.324036] [<812f9f3c>] __dev_change_flags+0xc0/0x17c[35088.334373] [<812fa020>] dev_change_flags+0x28/0x70[35088.344200] [<81310e10>] dev_ifsioc+0xf8/0x33c[35088.353155] [<81311528>] dev_ioctl+0x4d4/0x5e4[35088.362117] [<810fd580>] do_vfs_ioctl+0x5d4/0x63c[35088.371590] [<810fd638>] SyS_ioctl+0x50/0x94[35088.380208] [<810078d8>] syscall_common+0x30/0x54
这里在粘贴一遍call trace方便观看..
call trace展示的调用过程是从下到上的,dev_open这条调用之前的调用linux系统大致都一样,但是dev_open上面的,就和具体网卡有关系了
现在的症结在于,mtk的驱动打开interface的时候,由于没有申请到连续的内存空间而失败 warn_alloc_failed
