diff options
Diffstat (limited to 'kernel/marker.c')
| -rw-r--r-- | kernel/marker.c | 55 |
1 files changed, 22 insertions, 33 deletions
diff --git a/kernel/marker.c b/kernel/marker.c index b5a9fe1d50d5..971da5317903 100644 --- a/kernel/marker.c +++ b/kernel/marker.c | |||
| @@ -55,8 +55,8 @@ static DEFINE_MUTEX(markers_mutex); | |||
| 55 | struct marker_entry { | 55 | struct marker_entry { |
| 56 | struct hlist_node hlist; | 56 | struct hlist_node hlist; |
| 57 | char *format; | 57 | char *format; |
| 58 | void (*call)(const struct marker *mdata, /* Probe wrapper */ | 58 | /* Probe wrapper */ |
| 59 | void *call_private, const char *fmt, ...); | 59 | void (*call)(const struct marker *mdata, void *call_private, ...); |
| 60 | struct marker_probe_closure single; | 60 | struct marker_probe_closure single; |
| 61 | struct marker_probe_closure *multi; | 61 | struct marker_probe_closure *multi; |
| 62 | int refcount; /* Number of times armed. 0 if disarmed. */ | 62 | int refcount; /* Number of times armed. 0 if disarmed. */ |
| @@ -91,15 +91,13 @@ EXPORT_SYMBOL_GPL(__mark_empty_function); | |||
| 91 | * marker_probe_cb Callback that prepares the variable argument list for probes. | 91 | * marker_probe_cb Callback that prepares the variable argument list for probes. |
| 92 | * @mdata: pointer of type struct marker | 92 | * @mdata: pointer of type struct marker |
| 93 | * @call_private: caller site private data | 93 | * @call_private: caller site private data |
| 94 | * @fmt: format string | ||
| 95 | * @...: Variable argument list. | 94 | * @...: Variable argument list. |
| 96 | * | 95 | * |
| 97 | * Since we do not use "typical" pointer based RCU in the 1 argument case, we | 96 | * Since we do not use "typical" pointer based RCU in the 1 argument case, we |
| 98 | * need to put a full smp_rmb() in this branch. This is why we do not use | 97 | * need to put a full smp_rmb() in this branch. This is why we do not use |
| 99 | * rcu_dereference() for the pointer read. | 98 | * rcu_dereference() for the pointer read. |
| 100 | */ | 99 | */ |
| 101 | void marker_probe_cb(const struct marker *mdata, void *call_private, | 100 | void marker_probe_cb(const struct marker *mdata, void *call_private, ...) |
| 102 | const char *fmt, ...) | ||
| 103 | { | 101 | { |
| 104 | va_list args; | 102 | va_list args; |
| 105 | char ptype; | 103 | char ptype; |
| @@ -120,8 +118,9 @@ void marker_probe_cb(const struct marker *mdata, void *call_private, | |||
| 120 | /* Must read the ptr before private data. They are not data | 118 | /* Must read the ptr before private data. They are not data |
| 121 | * dependant, so we put an explicit smp_rmb() here. */ | 119 | * dependant, so we put an explicit smp_rmb() here. */ |
| 122 | smp_rmb(); | 120 | smp_rmb(); |
| 123 | va_start(args, fmt); | 121 | va_start(args, call_private); |
| 124 | func(mdata->single.probe_private, call_private, fmt, &args); | 122 | func(mdata->single.probe_private, call_private, mdata->format, |
| 123 | &args); | ||
| 125 | va_end(args); | 124 | va_end(args); |
| 126 | } else { | 125 | } else { |
| 127 | struct marker_probe_closure *multi; | 126 | struct marker_probe_closure *multi; |
| @@ -136,9 +135,9 @@ void marker_probe_cb(const struct marker *mdata, void *call_private, | |||
| 136 | smp_read_barrier_depends(); | 135 | smp_read_barrier_depends(); |
| 137 | multi = mdata->multi; | 136 | multi = mdata->multi; |
| 138 | for (i = 0; multi[i].func; i++) { | 137 | for (i = 0; multi[i].func; i++) { |
| 139 | va_start(args, fmt); | 138 | va_start(args, call_private); |
| 140 | multi[i].func(multi[i].probe_private, call_private, fmt, | 139 | multi[i].func(multi[i].probe_private, call_private, |
| 141 | &args); | 140 | mdata->format, &args); |
| 142 | va_end(args); | 141 | va_end(args); |
| 143 | } | 142 | } |
| 144 | } | 143 | } |
| @@ -150,13 +149,11 @@ EXPORT_SYMBOL_GPL(marker_probe_cb); | |||
| 150 | * marker_probe_cb Callback that does not prepare the variable argument list. | 149 | * marker_probe_cb Callback that does not prepare the variable argument list. |
| 151 | * @mdata: pointer of type struct marker | 150 | * @mdata: pointer of type struct marker |
| 152 | * @call_private: caller site private data | 151 | * @call_private: caller site private data |
| 153 | * @fmt: format string | ||
| 154 | * @...: Variable argument list. | 152 | * @...: Variable argument list. |
| 155 | * | 153 | * |
| 156 | * Should be connected to markers "MARK_NOARGS". | 154 | * Should be connected to markers "MARK_NOARGS". |
| 157 | */ | 155 | */ |
| 158 | void marker_probe_cb_noarg(const struct marker *mdata, | 156 | void marker_probe_cb_noarg(const struct marker *mdata, void *call_private, ...) |
| 159 | void *call_private, const char *fmt, ...) | ||
| 160 | { | 157 | { |
| 161 | va_list args; /* not initialized */ | 158 | va_list args; /* not initialized */ |
| 162 | char ptype; | 159 | char ptype; |
| @@ -172,7 +169,8 @@ void marker_probe_cb_noarg(const struct marker *mdata, | |||
| 172 | /* Must read the ptr before private data. They are not data | 169 | /* Must read the ptr before private data. They are not data |
| 173 | * dependant, so we put an explicit smp_rmb() here. */ | 170 | * dependant, so we put an explicit smp_rmb() here. */ |
| 174 | smp_rmb(); | 171 | smp_rmb(); |
| 175 | func(mdata->single.probe_private, call_private, fmt, &args); | 172 | func(mdata->single.probe_private, call_private, mdata->format, |
| 173 | &args); | ||
| 176 | } else { | 174 | } else { |
| 177 | struct marker_probe_closure *multi; | 175 | struct marker_probe_closure *multi; |
| 178 | int i; | 176 | int i; |
| @@ -186,8 +184,8 @@ void marker_probe_cb_noarg(const struct marker *mdata, | |||
| 186 | smp_read_barrier_depends(); | 184 | smp_read_barrier_depends(); |
| 187 | multi = mdata->multi; | 185 | multi = mdata->multi; |
| 188 | for (i = 0; multi[i].func; i++) | 186 | for (i = 0; multi[i].func; i++) |
| 189 | multi[i].func(multi[i].probe_private, call_private, fmt, | 187 | multi[i].func(multi[i].probe_private, call_private, |
| 190 | &args); | 188 | mdata->format, &args); |
| 191 | } | 189 | } |
| 192 | preempt_enable(); | 190 | preempt_enable(); |
| 193 | } | 191 | } |
| @@ -443,7 +441,7 @@ static int remove_marker(const char *name) | |||
| 443 | hlist_del(&e->hlist); | 441 | hlist_del(&e->hlist); |
| 444 | /* Make sure the call_rcu has been executed */ | 442 | /* Make sure the call_rcu has been executed */ |
| 445 | if (e->rcu_pending) | 443 | if (e->rcu_pending) |
| 446 | rcu_barrier(); | 444 | rcu_barrier_sched(); |
| 447 | kfree(e); | 445 | kfree(e); |
| 448 | return 0; | 446 | return 0; |
| 449 | } | 447 | } |
| @@ -478,7 +476,7 @@ static int marker_set_format(struct marker_entry **entry, const char *format) | |||
| 478 | hlist_del(&(*entry)->hlist); | 476 | hlist_del(&(*entry)->hlist); |
| 479 | /* Make sure the call_rcu has been executed */ | 477 | /* Make sure the call_rcu has been executed */ |
| 480 | if ((*entry)->rcu_pending) | 478 | if ((*entry)->rcu_pending) |
| 481 | rcu_barrier(); | 479 | rcu_barrier_sched(); |
| 482 | kfree(*entry); | 480 | kfree(*entry); |
| 483 | *entry = e; | 481 | *entry = e; |
| 484 | trace_mark(core_marker_format, "name %s format %s", | 482 | trace_mark(core_marker_format, "name %s format %s", |
| @@ -657,7 +655,7 @@ int marker_probe_register(const char *name, const char *format, | |||
| 657 | * make sure it's executed now. | 655 | * make sure it's executed now. |
| 658 | */ | 656 | */ |
| 659 | if (entry->rcu_pending) | 657 | if (entry->rcu_pending) |
| 660 | rcu_barrier(); | 658 | rcu_barrier_sched(); |
| 661 | old = marker_entry_add_probe(entry, probe, probe_private); | 659 | old = marker_entry_add_probe(entry, probe, probe_private); |
| 662 | if (IS_ERR(old)) { | 660 | if (IS_ERR(old)) { |
| 663 | ret = PTR_ERR(old); | 661 | ret = PTR_ERR(old); |
| @@ -672,10 +670,7 @@ int marker_probe_register(const char *name, const char *format, | |||
| 672 | entry->rcu_pending = 1; | 670 | entry->rcu_pending = 1; |
| 673 | /* write rcu_pending before calling the RCU callback */ | 671 | /* write rcu_pending before calling the RCU callback */ |
| 674 | smp_wmb(); | 672 | smp_wmb(); |
| 675 | #ifdef CONFIG_PREEMPT_RCU | 673 | call_rcu_sched(&entry->rcu, free_old_closure); |
| 676 | synchronize_sched(); /* Until we have the call_rcu_sched() */ | ||
| 677 | #endif | ||
| 678 | call_rcu(&entry->rcu, free_old_closure); | ||
| 679 | end: | 674 | end: |
| 680 | mutex_unlock(&markers_mutex); | 675 | mutex_unlock(&markers_mutex); |
| 681 | return ret; | 676 | return ret; |
| @@ -706,7 +701,7 @@ int marker_probe_unregister(const char *name, | |||
| 706 | if (!entry) | 701 | if (!entry) |
| 707 | goto end; | 702 | goto end; |
| 708 | if (entry->rcu_pending) | 703 | if (entry->rcu_pending) |
| 709 | rcu_barrier(); | 704 | rcu_barrier_sched(); |
| 710 | old = marker_entry_remove_probe(entry, probe, probe_private); | 705 | old = marker_entry_remove_probe(entry, probe, probe_private); |
| 711 | mutex_unlock(&markers_mutex); | 706 | mutex_unlock(&markers_mutex); |
| 712 | marker_update_probes(); /* may update entry */ | 707 | marker_update_probes(); /* may update entry */ |
| @@ -718,10 +713,7 @@ int marker_probe_unregister(const char *name, | |||
| 718 | entry->rcu_pending = 1; | 713 | entry->rcu_pending = 1; |
| 719 | /* write rcu_pending before calling the RCU callback */ | 714 | /* write rcu_pending before calling the RCU callback */ |
| 720 | smp_wmb(); | 715 | smp_wmb(); |
| 721 | #ifdef CONFIG_PREEMPT_RCU | 716 | call_rcu_sched(&entry->rcu, free_old_closure); |
| 722 | synchronize_sched(); /* Until we have the call_rcu_sched() */ | ||
| 723 | #endif | ||
| 724 | call_rcu(&entry->rcu, free_old_closure); | ||
| 725 | remove_marker(name); /* Ignore busy error message */ | 717 | remove_marker(name); /* Ignore busy error message */ |
| 726 | ret = 0; | 718 | ret = 0; |
| 727 | end: | 719 | end: |
| @@ -788,7 +780,7 @@ int marker_probe_unregister_private_data(marker_probe_func *probe, | |||
| 788 | goto end; | 780 | goto end; |
| 789 | } | 781 | } |
| 790 | if (entry->rcu_pending) | 782 | if (entry->rcu_pending) |
| 791 | rcu_barrier(); | 783 | rcu_barrier_sched(); |
| 792 | old = marker_entry_remove_probe(entry, NULL, probe_private); | 784 | old = marker_entry_remove_probe(entry, NULL, probe_private); |
| 793 | mutex_unlock(&markers_mutex); | 785 | mutex_unlock(&markers_mutex); |
| 794 | marker_update_probes(); /* may update entry */ | 786 | marker_update_probes(); /* may update entry */ |
| @@ -799,10 +791,7 @@ int marker_probe_unregister_private_data(marker_probe_func *probe, | |||
| 799 | entry->rcu_pending = 1; | 791 | entry->rcu_pending = 1; |
| 800 | /* write rcu_pending before calling the RCU callback */ | 792 | /* write rcu_pending before calling the RCU callback */ |
| 801 | smp_wmb(); | 793 | smp_wmb(); |
| 802 | #ifdef CONFIG_PREEMPT_RCU | 794 | call_rcu_sched(&entry->rcu, free_old_closure); |
| 803 | synchronize_sched(); /* Until we have the call_rcu_sched() */ | ||
| 804 | #endif | ||
| 805 | call_rcu(&entry->rcu, free_old_closure); | ||
| 806 | remove_marker(entry->name); /* Ignore busy error message */ | 795 | remove_marker(entry->name); /* Ignore busy error message */ |
| 807 | end: | 796 | end: |
| 808 | mutex_unlock(&markers_mutex); | 797 | mutex_unlock(&markers_mutex); |
