Hi Philippe,

actually, I was trying to apply a micro-optimisation on
__ipipe_handle_irq, but I think I also found a bug on SMP systems (at
least on x86):

After __ipipe_handle_irq forwarded some IRQ to __ipipe_dispatch_wired
and the latter returned 1 (i.e. "not deferred"), a pipeline sync is
triggered using the cpuid read on IRQ entry. But I think that
__ipipe_dispatch_wired may very well have caused some CPU migration of
the current context so that reloading the cpuid is required here. This
is what the first attached patch does.

Jan


PS: The optimisation I was looking at deals with the assumption that a
wired IRQ may never be also a sticky one, correct? If yes, the second
(alternative) patch might be interesting as it avoids to touch the root
domain data structure and to test for stickiness in the wired case.
Should shorten the wired IRQ path by a few cycles (or more on cache
miss...).
Index: linux-2.6.19/arch/i386/kernel/ipipe.c
===================================================================
--- linux-2.6.19.orig/arch/i386/kernel/ipipe.c
+++ linux-2.6.19/arch/i386/kernel/ipipe.c
@@ -790,9 +790,10 @@ int __ipipe_handle_irq(struct pt_regs re
                if (likely(test_bit(IPIPE_WIRED_FLAG, 
&next_domain->irqs[irq].control))) {
                        if (!m_ack && next_domain->irqs[irq].acknowledge != 
NULL)
                                next_domain->irqs[irq].acknowledge(irq);
-                       if (likely(__ipipe_dispatch_wired(next_domain, irq)))
+                       if (likely(__ipipe_dispatch_wired(next_domain, irq))) {
+                               ipipe_load_cpuid();
                                goto finalize;
-                       else
+                       } else
                                goto finalize_nosync;
                }
        }
Index: linux-2.6.19/arch/i386/kernel/ipipe.c
===================================================================
--- linux-2.6.19.orig/arch/i386/kernel/ipipe.c
+++ linux-2.6.19/arch/i386/kernel/ipipe.c
@@ -772,30 +772,30 @@ int __ipipe_handle_irq(struct pt_regs re
        ipipe_declare_cpuid;
        int m_ack;
 
-       ipipe_load_cpuid();
-
        if (regs.orig_eax < 0) {
                irq = ~irq;
                m_ack = 0;
        } else
                m_ack = 1;
 
+       head = __ipipe_pipeline.next;
+       next_domain = list_entry(head, struct ipipe_domain, p_link);
+       if (likely(test_bit(IPIPE_WIRED_FLAG, 
&next_domain->irqs[irq].control))) {
+               if (!m_ack && next_domain->irqs[irq].acknowledge != NULL)
+                       next_domain->irqs[irq].acknowledge(irq);
+               if (likely(__ipipe_dispatch_wired(next_domain, irq))) {
+                       ipipe_load_cpuid();
+                       goto finalize;
+               } else
+                       goto finalize_nosync;
+       }
+
+       ipipe_load_cpuid();
+
        this_domain = per_cpu(ipipe_percpu_domain, cpuid);
 
        if (test_bit(IPIPE_STICKY_FLAG, &this_domain->irqs[irq].control))
                head = &this_domain->p_link;
-       else {
-               head = __ipipe_pipeline.next;
-               next_domain = list_entry(head, struct ipipe_domain, p_link);
-               if (likely(test_bit(IPIPE_WIRED_FLAG, 
&next_domain->irqs[irq].control))) {
-                       if (!m_ack && next_domain->irqs[irq].acknowledge != 
NULL)
-                               next_domain->irqs[irq].acknowledge(irq);
-                       if (likely(__ipipe_dispatch_wired(next_domain, irq)))
-                               goto finalize;
-                       else
-                               goto finalize_nosync;
-               }
-       }
 
        /* Ack the interrupt. */
 

Attachment: signature.asc
Description: OpenPGP digital signature

_______________________________________________
Adeos-main mailing list
[email protected]
https://mail.gna.org/listinfo/adeos-main

Reply via email to