22/* Code to implement cross-cpu calling for Dtrace. */
33/* Author: Paul D. Fox */
44/* Date: May 2011 */
5+ /* $Header: $ */
56/**********************************************************************/
7+
8+ /**********************************************************************/
9+ /* Bit of madness/strangeness here. If we are not GPL, then "apic" */
10+ /* (symbol) isnt accessible to us. We dont care, but theres a bug */
11+ /* in gcc/ld and <asm/ipi.h> because of static/inline functions */
12+ /* refer to "apic" even tho we dont use it. So, we #define it out */
13+ /* of harms way, and then, to avoid an undefined symbol reference */
14+ /* (which we didnt want), we define our own "hello_apic". I told */
15+ /* you it was strange. */
16+ /**********************************************************************/
17+
18+ #define apic hello_apic
619#include <linux/mm.h>
720# undef zone
821# define zone linux_zone
1124#include "dtrace_proto.h"
1225
1326#include <linux/cpumask.h>
14- #include <linux/errno.h>
15- #include <linux/miscdevice.h>
16- #include <linux/fs.h>
17- #include <linux/proc_fs.h>
18- #include <linux/module.h>
19- #include <linux/slab.h>
20- #include <linux/sys.h>
21- #include <linux/thread_info.h>
22- #include <linux/smp.h>
2327#include <asm/smp.h>
24- #include <linux/vmalloc.h>
25- #include <asm/current.h>
26- #include <asm/desc.h>
27- #include <asm/hardirq.h>
2828#include <asm/ipi.h>
2929
30+ struct apic * hello_apic ; /* Define this because apic.h is broken when facing a */
31+ /* non-GPL driver. We get an undefined, so define it. */
32+ /* We use dynamic lookup instead. */
33+ struct apic * x_apic ;
3034
3135extern void dtrace_sync_func (void );
3236int in_xcall = -1 ;
@@ -97,6 +101,21 @@ static void dump_xcalls(void);
97101static void send_ipi_interrupt (cpumask_t * mask , int vector );
98102void xcall_slave2 (void );
99103
104+ /**********************************************************************/
105+ /* Called during driver startup to do one time initialisation, so */
106+ /* we dont end up doing symbol lookups in potentially critical */
107+ /* probe paths. */
108+ /**********************************************************************/
109+ void
110+ xcall_init (void )
111+ {
112+ if ((x_apic = get_proc_addr ("apic" )) == NULL ) {
113+ dtrace_linux_panic ("init_xcall: cannot locate 'apic'\n" );
114+ return ;
115+ }
116+ x_apic = * (void * * ) x_apic ;
117+ }
118+
100119/**********************************************************************/
101120/* Switch the interface from the orig dtrace_xcall code to the new */
102121/* code. As of 20110520, I cannot decide which one is worse. The */
@@ -531,7 +550,7 @@ send_ipi_interrupt(cpumask_t *mask, int vector)
531550# elif LINUX_VERSION_CODE < KERNEL_VERSION (2 , 6 , 28 )
532551 send_IPI_mask (* mask , vector );
533552# else
534- apic -> send_IPI_mask (mask , vector );
553+ x_apic -> send_IPI_mask (mask , vector );
535554# endif
536555}
537556/**********************************************************************/
@@ -547,7 +566,17 @@ xcall_slave(void)
547566
548567 smp_mb ();
549568
550- ack_APIC_irq ();
569+ /***********************************************/
570+ /* We want to call ack_APIC_irq, but we */
571+ /* inline the expansion because of the GPL */
572+ /* symbol issue. */
573+ /* Once we do this, we can have more IPI */
574+ /* interrupts arrive (but not until we exit */
575+ /* the interrupt routine and re-enable */
576+ /* interrupts). */
577+ /***********************************************/
578+ x_apic -> write (APIC_EOI , 0 );
579+ //ack_APIC_irq();
551580}
552581void
553582xcall_slave2 (void )
0 commit comments