Too much work at interrupt, IntrStatus=0x0040

Есть у меня один роутер, который в основном играет роль фаервола. На роуте стоит linux red hat 9, который я там перековыриваю уже несколько лет. Так вот на этом роутере стоит 3 почти одинаковые сетевухи — RealTek RTL8139, две RTL-8139C и одна RTL-8100B/8139D.

Так вот, не помню точно когда, но у меня возникла проблема с тем, что линукс тупо блокировал одну из сетевух, а в логах писало «…eth1: Too much work at interrupt…». На другом конце стоит винда со встроенной сетевухой. Короче проблема возникла и я не понимал её причины. Кстати, при старте системы мне почему-то выдаёт 10Mbps, half-duplex, хотя на самом деле работает на 100! Поискав в инете я ничего толком не нашёл. Первый раз, когда я столкнулся с ней, всё каким-то образом решилось… точно не помню как, но по-моему я выставил принудительно 10мбит в винде и после этого этот прикол исчез. Прошло пару лет и недавно я опять столкнулся с этой проблемой (по причине переустановки винды). При этом я уже не помнил, что я там такого сделал. Я снова полез в инет и тщательно искал всё, что касается данной проблемы. Самый дельный совет заключался в смене сетевухи, но я такую роскошь себе не могу позволить. Все указывали на возможную проблему или баг в драйвере.

Файл драйвера называется 8139too, я сразу полез в исходники глянуть что там в 8139too.c и вот соответствующие строки, которые отвечают за эту ошибку:

[...]
/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
static int max_interrupt_work = 20;
[...]
        if (boguscnt <= 0) {
                printk (KERN_WARNING "%s: Too much work at interrupt, "
                        "IntrStatus=0x%4.4x.\n", dev->name, status);

                /* Clear all interrupt sources. */
                RTL_W16 (IntrStatus, 0xffff);
        }
[...]

Конечно понять в чём причина для меня сложно. Но факт, что это происходит, но не должно происходить. Кстати, в новой версии драйвера для ядра 2.6, этого кода нет, вообще функция переписана. Так вот попробовал банально увеличить количество max_interrupt_work в 2, то есть поставить 40, пересобрать ядро и глянуть как оно будет. Но, к сожалению, никакого результата полезного это не принесло и сетевуха всё равно висла.

Вдруг я вспомнил про такую утилиту, как mii-tool. Вот она как раз и помогла. Запускаем:

mii-tool -r

И после этого всё работает нормально. 🙂

Какой-то трабл с согласованием (negotiation). Если просто запустить mii-tool -v, то оно выдаёт, что скорость определена принудительно, а не по согласованию и из-за этого видимо возникает такая проблема.

Короче, написал это для того, чтоб те, у кого возникает подобная проблема, смогли найти решение 🙂

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *