--- linux/net/core/dev.c.orig +++ linux/net/core/dev.c @@ -1403,6 +1403,7 @@ out: =======================================================================*/ int netdev_max_backlog = 8; +int netdev_backlog_granularity = 1; int weight_p = 64; /* old backlog weight */ /* These numbers are selected based on intuition and some * experimentatiom, if you have more scientific way of doing this @@ -1903,7 +1904,8 @@ static void net_rx_action(struct softirq { struct softnet_data *queue = &__get_cpu_var(softnet_data); unsigned long start_time = jiffies; - int budget = netdev_max_backlog; + int budget = netdev_max_backlog, left, + gran = netdev_backlog_granularity; local_irq_disable(); @@ -1926,7 +1928,8 @@ static void net_rx_action(struct softirq dev = list_entry(queue->poll_list.next, struct net_device, poll_list); - if (dev->quota <= 0 || dev->poll(dev, &budget)) { + left = gran; + if (dev->quota <= 0 || dev->poll(dev, &left)) { local_irq_disable(); list_del(&dev->poll_list); list_add_tail(&dev->poll_list, &queue->poll_list); @@ -1938,6 +1941,7 @@ static void net_rx_action(struct softirq dev_put(dev); local_irq_disable(); } + budget -= gran - left; } out: local_irq_enable(); --- linux/net/core/sysctl_net_core.c.orig +++ linux/net/core/sysctl_net_core.c @@ -12,7 +12,7 @@ #ifdef CONFIG_SYSCTL -extern int netdev_max_backlog; +extern int netdev_max_backlog, netdev_backlog_granularity; extern int weight_p; extern int no_cong_thresh; extern int no_cong; @@ -99,6 +99,14 @@ ctl_table core_table[] = { .proc_handler = &proc_dointvec }, { + .ctl_name = NET_CORE_MAX_BACKLOG, + .procname = "netdev_backlog_granularity", + .data = &netdev_backlog_granularity, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = &proc_dointvec + }, + { .ctl_name = NET_CORE_NO_CONG_THRESH, .procname = "no_cong_thresh", .data = &no_cong_thresh,