Re: [patch] voluntary-preempt-2.6.9-rc1-bk4-Q5

From: Ingo Molnar
Date: Mon Aug 30 2004 - 13:19:34 EST



* Thomas Charbonnel <thomas@xxxxxxxxxx> wrote:

> Ingo Molnar wrote :
> > i've uploaded -Q5 to:
> >
> > http://redhat.com/~mingo/voluntary-preempt/voluntary-preempt-2.6.9-rc1-bk4-Q5
> >
>
> Here are the problematic spots for me with Q5:
>
> rtl8139_poll (this one was also present with previous versions of the
> patch) :
> http://www.undata.org/~thomas/q5_rtl8139.trace

ok, rx processing latency again. You've set netdev_max_backlog to a low
value, right? I think we can break this particular loop independently of
netdev_max_backlog, could you try the attached patch ontop of -Q5, does
it help?

> =======>
> 00000001 0.000ms (+0.000ms): resolve_symbol (simplify_symbols)
> 00000001 0.000ms (+0.000ms): __find_symbol (resolve_symbol)
> 00000001 0.154ms (+0.154ms): use_module (resolve_symbol)
> 00000001 0.154ms (+0.000ms): sub_preempt_count (resolve_symbol)

seems resolve_symbol() is quite expensive ... no idea how to fix this
one right away, it seems to be pure algorithmic overhead.

> and a weird one with do_timer (called from do_IRQ) taking more than 1ms
> to complete :
> http://www.undata.org/~thomas/do_irq.trace

hm, indeed this is a weird one. 1 msec is too close to the timer
frequency to be accidental. According to the trace:

00010000 0.002ms (+0.000ms): timer_interrupt (generic_handle_IRQ_event)
00010001 0.002ms (+0.000ms): mark_offset_tsc (timer_interrupt)
00010001 1.028ms (+1.025ms): do_timer (timer_interrupt)
00010001 1.028ms (+0.000ms): update_process_times (do_timer)

the latency happened between the beginning of mark_offset_tsc() and the
calling of do_timer() - i.e. the delay happened somewhere within
mark_offset_tsc() itself. Is this an SMP system?

Ingo
--- linux/net/core/dev.c.orig2
+++ linux/net/core/dev.c
@@ -1903,7 +1903,7 @@ 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, loops;


local_irq_disable();
@@ -1926,7 +1926,10 @@ 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)) {
+ loops = 1;
+ if (dev->quota <= 0 || dev->poll(dev, &loops)) {
+ if (loops < 1)
+ budget--;
local_irq_disable();
list_del(&dev->poll_list);
list_add_tail(&dev->poll_list, &queue->poll_list);