Commit 7acf8a1e authored by Matthew Whitehead's avatar Matthew Whitehead Committed by David S. Miller

Replace 2 jiffies with sysctl netdev_budget_usecs to enable softirq tuning

Constants used for tuning are generally a bad idea, especially as hardware
changes over time. Replace the constant 2 jiffies with sysctl variable
netdev_budget_usecs to enable sysadmins to tune the softirq processing.
Also document the variable.

For example, a very fast machine might tune this to 1000 microseconds,
while my regression testing 486DX-25 needs it to be 4000 microseconds on
a nearly idle network to prevent time_squeeze from being incremented.

Version 2: changed jiffies to microseconds for predictable units.
Signed-off-by: default avatarMatthew Whitehead <tedheadster@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 20da848f
...@@ -188,7 +188,16 @@ netdev_budget ...@@ -188,7 +188,16 @@ netdev_budget
Maximum number of packets taken from all interfaces in one polling cycle (NAPI Maximum number of packets taken from all interfaces in one polling cycle (NAPI
poll). In one polling cycle interfaces which are registered to polling are poll). In one polling cycle interfaces which are registered to polling are
probed in a round-robin manner. probed in a round-robin manner. Also, a polling cycle may not exceed
netdev_budget_usecs microseconds, even if netdev_budget has not been
exhausted.
netdev_budget_usecs
---------------------
Maximum number of microseconds in one NAPI polling cycle. Polling
will exit when either netdev_budget_usecs have elapsed during the
poll cycle or the number of packets processed reaches netdev_budget.
netdev_max_backlog netdev_max_backlog
------------------ ------------------
......
...@@ -3296,6 +3296,7 @@ static __always_inline int ____dev_forward_skb(struct net_device *dev, ...@@ -3296,6 +3296,7 @@ static __always_inline int ____dev_forward_skb(struct net_device *dev,
void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev); void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev);
extern int netdev_budget; extern int netdev_budget;
extern unsigned int netdev_budget_usecs;
/* Called by rtnetlink.c:rtnl_unlock() */ /* Called by rtnetlink.c:rtnl_unlock() */
void netdev_run_todo(void); void netdev_run_todo(void);
......
...@@ -274,6 +274,7 @@ enum ...@@ -274,6 +274,7 @@ enum
NET_CORE_AEVENT_ETIME=20, NET_CORE_AEVENT_ETIME=20,
NET_CORE_AEVENT_RSEQTH=21, NET_CORE_AEVENT_RSEQTH=21,
NET_CORE_WARNINGS=22, NET_CORE_WARNINGS=22,
NET_CORE_BUDGET_USECS=23,
}; };
/* /proc/sys/net/ethernet */ /* /proc/sys/net/ethernet */
......
...@@ -197,6 +197,7 @@ static const struct bin_table bin_net_core_table[] = { ...@@ -197,6 +197,7 @@ static const struct bin_table bin_net_core_table[] = {
{ CTL_INT, NET_CORE_AEVENT_ETIME, "xfrm_aevent_etime" }, { CTL_INT, NET_CORE_AEVENT_ETIME, "xfrm_aevent_etime" },
{ CTL_INT, NET_CORE_AEVENT_RSEQTH, "xfrm_aevent_rseqth" }, { CTL_INT, NET_CORE_AEVENT_RSEQTH, "xfrm_aevent_rseqth" },
{ CTL_INT, NET_CORE_WARNINGS, "warnings" }, { CTL_INT, NET_CORE_WARNINGS, "warnings" },
{ CTL_INT, NET_CORE_BUDGET_USECS, "netdev_budget_usecs" },
{}, {},
}; };
......
...@@ -3441,6 +3441,7 @@ EXPORT_SYMBOL(netdev_max_backlog); ...@@ -3441,6 +3441,7 @@ EXPORT_SYMBOL(netdev_max_backlog);
int netdev_tstamp_prequeue __read_mostly = 1; int netdev_tstamp_prequeue __read_mostly = 1;
int netdev_budget __read_mostly = 300; int netdev_budget __read_mostly = 300;
unsigned int __read_mostly netdev_budget_usecs = 2000;
int weight_p __read_mostly = 64; /* old backlog weight */ int weight_p __read_mostly = 64; /* old backlog weight */
int dev_weight_rx_bias __read_mostly = 1; /* bias for backlog weight */ int dev_weight_rx_bias __read_mostly = 1; /* bias for backlog weight */
int dev_weight_tx_bias __read_mostly = 1; /* bias for output_queue quota */ int dev_weight_tx_bias __read_mostly = 1; /* bias for output_queue quota */
...@@ -5307,7 +5308,8 @@ static int napi_poll(struct napi_struct *n, struct list_head *repoll) ...@@ -5307,7 +5308,8 @@ static int napi_poll(struct napi_struct *n, struct list_head *repoll)
static __latent_entropy void net_rx_action(struct softirq_action *h) static __latent_entropy void net_rx_action(struct softirq_action *h)
{ {
struct softnet_data *sd = this_cpu_ptr(&softnet_data); struct softnet_data *sd = this_cpu_ptr(&softnet_data);
unsigned long time_limit = jiffies + 2; unsigned long time_limit = jiffies +
usecs_to_jiffies(netdev_budget_usecs);
int budget = netdev_budget; int budget = netdev_budget;
LIST_HEAD(list); LIST_HEAD(list);
LIST_HEAD(repoll); LIST_HEAD(repoll);
......
...@@ -452,6 +452,14 @@ static struct ctl_table net_core_table[] = { ...@@ -452,6 +452,14 @@ static struct ctl_table net_core_table[] = {
.extra1 = &one, .extra1 = &one,
.extra2 = &max_skb_frags, .extra2 = &max_skb_frags,
}, },
{
.procname = "netdev_budget_usecs",
.data = &netdev_budget_usecs,
.maxlen = sizeof(unsigned int),
.mode = 0644,
.proc_handler = proc_dointvec_minmax,
.extra1 = &zero,
},
{ } { }
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment