Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Merge branch 'devel'
[palacios.git] / kitten / kernel / xcall.c
1 #include <lwk/kernel.h>
2 #include <lwk/smp.h>
3 #include <lwk/xcall.h>
4
5 /**
6  * Carries out an inter-CPU function call. The specified function is executed
7  * on all of the target CPUs that are currently online and executes in 
8  * interrupt context with interrupts disabled... it must not block and should
9  * be short.
10  *
11  * Arguments:
12  *       [IN] cpu_mask: The target CPUs of the cross-call.
13  *       [IN] func:     The function to execute on each target CPU.
14  *       [IN] info:     Argument to pass to func().
15  *       [IN] wait:     true = wait for cross-call to fully complete.
16  *
17  * Returns:
18  *       Success: 0
19  *       Failure: Error code
20  *
21  * NOTE: If wait=0, care must be taken to ensure that the data pointed to by
22  *       the info argument remains valid until the cross-call function func()
23  *       completes on all target CPUs.
24  */
25 int
26 xcall_function(
27         cpumask_t       cpu_mask,
28         void            (*func)(void *info),
29         void *          info,
30         bool            wait
31 )
32 {
33         bool contains_me;
34         int status;
35
36         BUG_ON(irqs_disabled());
37         BUG_ON(!func);
38
39         /* Only target online CPUs */
40         cpus_and(cpu_mask, cpu_mask, cpu_online_map);
41
42         /* No need to xcall ourself... we'll just call func() directly */
43         if ((contains_me = cpu_isset(this_cpu, cpu_mask)))
44                 cpu_clear(this_cpu, cpu_mask);
45
46         /* Perform xcall to remote CPUs */
47         if ((status = arch_xcall_function(cpu_mask, func, info, wait)))
48                 return status;
49
50         /* Call func() on the local CPU, if it was in cpu_mask */
51         if (contains_me)
52                 (*func)(info);
53
54         return 0;
55 }
56
57 /**
58  * Sends a reschedule inter-processor interrupt to the target CPU.
59  * This causes the target CPU to call schedule().
60  *
61  * NOTE: It is safe to call this with locks held and interrupts
62  *       disabled so long as the caller will drop the locks and
63  *       re-enable interrupts "soon", independent of whether the
64  *       target actually receives the reschedule interrupt. 
65  *       Deadlock may occur if these conditions aren't met.
66  */
67 void
68 xcall_reschedule(id_t cpu)
69 {
70         arch_xcall_reschedule(cpu);
71 }