| 1 | |
| 2 | #define MARK_TRAP 1 |
| 3 | #define _MARK_TRAP (1 << MARK_TRAP) |
| 4 | Can generate a trap |
| 5 | |
| 6 | #define MARK_PREEMPT 2 |
| 7 | #define _MARK_PREEMPT (1 << MARK_PREEMPT) |
| 8 | Permits blocking calls within probe. |
| 9 | How to deal with probe removal : |
| 10 | Each site has its per cpu probe_exec counters. The sum of the signed values |
| 11 | gives the number of executors. Operations inc/dec on those values are done |
| 12 | within preempt disable so they can be done non atomically without risking |
| 13 | to be corrupted by another CPU. |
| 14 | 1 - disable site and remove call |
| 15 | 2 - while sum of probe_exec counters != 0, sleep 50ms |
| 16 | fail after 10 loops |
| 17 | - if someone sleeps in here for a long time or waits for |
| 18 | a busy ressource, removal may fail with -EBUSY. |
| 19 | |
| 20 | site : |
| 21 | |
| 22 | if (enable) { |
| 23 | preempt_disable(); |
| 24 | probe_exec[smp_processor_id()]++; |
| 25 | preempt_enable(); |
| 26 | handler(); |
| 27 | preempt_disable(); |
| 28 | probe_exec[smp_processor_id()]--; |
| 29 | preempt_enable(); |
| 30 | } |
| 31 | |
| 32 | #define MARK_RESCHED 3 |
| 33 | #define _MARK_RESCHED (1 << MARK_RESCHED) |
| 34 | preempt_schedule() will be called by the marker. |
| 35 | |
| 36 | #define MARK_PRINTK 4 |
| 37 | #define _MARK_PRINTK (1 << MARK_PRINTK) |
| 38 | vprintk can be called in the probe/printk can be called as probe. |
| 39 | |
| 40 | #define MARK_LOCK_SAFE |
| 41 | #define _MARK_LOCK_SAFE (1 << MARK_LOCK_SAFE) |
| 42 | It is completely safe to take a lock, disable irqs, softirqs, ... from this marker. |
| 43 | If unset, checking the context must be done to insure no deadlock or recursive |
| 44 | call will occur. |
| 45 | |
| 46 | #define _MARK_DEFAULT (_MARK_TRAP | _MARK_RESCHED | _MARK_PRINTK) |
| 47 | |
| 48 | #define MARK (format, args...) _MARK(MARK_DEFAULT, format, ## args) |
| 49 | |
| 50 | ex. i386 |
| 51 | #define _MARK(opt, format, args...) \ |
| 52 | do { \ |
| 53 | if (opt & _MARK_TRAP) \ |
| 54 | MARK(opt, format, ## args); \ |
| 55 | else \ |
| 56 | GEN_MARK(opt, format, ## args); \ |
| 57 | } while (0) |
| 58 | |
| 59 | ex. powerpc |
| 60 | #define _MARK(opt, format, args...) MARK(opt, format, ## args); |
| 61 | |
| 62 | |
| 63 | MARK(opt, format, ...) \ |
| 64 | static declare opt in struct; \ |
| 65 | if (enable) { |
| 66 | preempt_disable(); |
| 67 | if (opt & _MARK_PREEMPT) { |
| 68 | probe_exec[smp_processor_id()]++; |
| 69 | if (opt & _MARK_RESCHED) |
| 70 | preempt_enable(); |
| 71 | else |
| 72 | preempt_enable_no_resched(); |
| 73 | } |
| 74 | handler(); |
| 75 | if (opt & _MARK_PREEMPT) { |
| 76 | preempt_disable(); |
| 77 | probe_exec[smp_processor_id()]--; |
| 78 | } |
| 79 | if (opt & _MARK_RESCHED) |
| 80 | preempt_enable(); |
| 81 | else |
| 82 | preempt_enable_no_resched(); |
| 83 | } |
| 84 | |
| 85 | |
| 86 | |