aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/jump_label.c
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2011-12-25 08:44:43 -0500
committerAvi Kivity <avi@redhat.com>2011-12-27 04:22:24 -0500
commit9e31905f293ae84e4f120ed9e414031eaefa0bdf (patch)
tree153204ff0dca820e760007bc24075ec7fb46a276 /kernel/jump_label.c
parentff5c2c0316ff0e3e2dba3ca14167d994453df093 (diff)
parentb3d9468a8bd218a695e3a0ff112cd4efd27b670a (diff)
Merge remote-tracking branch 'tip/perf/core' into kvm-updates/3.3
* tip/perf/core: (66 commits) perf, x86: Expose perf capability to other modules perf, x86: Implement arch event mask as quirk x86, perf: Disable non available architectural events jump_label: Provide jump_label_key initializers jump_label, x86: Fix section mismatch perf, core: Rate limit perf_sched_events jump_label patching perf: Fix enable_on_exec for sibling events perf: Remove superfluous arguments perf, x86: Prefer fixed-purpose counters when scheduling perf, x86: Fix event scheduler for constraints with overlapping counters perf, x86: Implement event scheduler helper functions perf: Avoid a useless pmu_disable() in the perf-tick x86/tools: Add decoded instruction dump mode x86: Update instruction decoder to support new AVX formats x86/tools: Fix insn_sanity message outputs x86/tools: Fix instruction decoder message output x86: Fix instruction decoder to handle grouped AVX instructions x86/tools: Fix Makefile to build all test tools perf test: Soft errors shouldn't stop the "Validate PERF_RECORD_" test perf test: Validate PERF_RECORD_ events and perf_sample fields ... Signed-off-by: Avi Kivity <avi@redhat.com> * commit 'b3d9468a8bd218a695e3a0ff112cd4efd27b670a': (66 commits) perf, x86: Expose perf capability to other modules perf, x86: Implement arch event mask as quirk x86, perf: Disable non available architectural events jump_label: Provide jump_label_key initializers jump_label, x86: Fix section mismatch perf, core: Rate limit perf_sched_events jump_label patching perf: Fix enable_on_exec for sibling events perf: Remove superfluous arguments perf, x86: Prefer fixed-purpose counters when scheduling perf, x86: Fix event scheduler for constraints with overlapping counters perf, x86: Implement event scheduler helper functions perf: Avoid a useless pmu_disable() in the perf-tick x86/tools: Add decoded instruction dump mode x86: Update instruction decoder to support new AVX formats x86/tools: Fix insn_sanity message outputs x86/tools: Fix instruction decoder message output x86: Fix instruction decoder to handle grouped AVX instructions x86/tools: Fix Makefile to build all test tools perf test: Soft errors shouldn't stop the "Validate PERF_RECORD_" test perf test: Validate PERF_RECORD_ events and perf_sample fields ...
Diffstat (limited to 'kernel/jump_label.c')
-rw-r--r--kernel/jump_label.c49
1 files changed, 42 insertions, 7 deletions
diff --git a/kernel/jump_label.c b/kernel/jump_label.c
index 2af9027106a8..01d3b70fc98a 100644
--- a/kernel/jump_label.c
+++ b/kernel/jump_label.c
@@ -73,16 +73,47 @@ void jump_label_inc(struct jump_label_key *key)
73} 73}
74EXPORT_SYMBOL_GPL(jump_label_inc); 74EXPORT_SYMBOL_GPL(jump_label_inc);
75 75
76void jump_label_dec(struct jump_label_key *key) 76static void __jump_label_dec(struct jump_label_key *key,
77 unsigned long rate_limit, struct delayed_work *work)
77{ 78{
78 if (!atomic_dec_and_mutex_lock(&key->enabled, &jump_label_mutex)) 79 if (!atomic_dec_and_mutex_lock(&key->enabled, &jump_label_mutex))
79 return; 80 return;
80 81
81 jump_label_update(key, JUMP_LABEL_DISABLE); 82 if (rate_limit) {
83 atomic_inc(&key->enabled);
84 schedule_delayed_work(work, rate_limit);
85 } else
86 jump_label_update(key, JUMP_LABEL_DISABLE);
87
82 jump_label_unlock(); 88 jump_label_unlock();
83} 89}
84EXPORT_SYMBOL_GPL(jump_label_dec); 90EXPORT_SYMBOL_GPL(jump_label_dec);
85 91
92static void jump_label_update_timeout(struct work_struct *work)
93{
94 struct jump_label_key_deferred *key =
95 container_of(work, struct jump_label_key_deferred, work.work);
96 __jump_label_dec(&key->key, 0, NULL);
97}
98
99void jump_label_dec(struct jump_label_key *key)
100{
101 __jump_label_dec(key, 0, NULL);
102}
103
104void jump_label_dec_deferred(struct jump_label_key_deferred *key)
105{
106 __jump_label_dec(&key->key, key->timeout, &key->work);
107}
108
109
110void jump_label_rate_limit(struct jump_label_key_deferred *key,
111 unsigned long rl)
112{
113 key->timeout = rl;
114 INIT_DELAYED_WORK(&key->work, jump_label_update_timeout);
115}
116
86static int addr_conflict(struct jump_entry *entry, void *start, void *end) 117static int addr_conflict(struct jump_entry *entry, void *start, void *end)
87{ 118{
88 if (entry->code <= (unsigned long)end && 119 if (entry->code <= (unsigned long)end &&
@@ -113,7 +144,7 @@ static int __jump_label_text_reserved(struct jump_entry *iter_start,
113 * running code can override this to make the non-live update case 144 * running code can override this to make the non-live update case
114 * cheaper. 145 * cheaper.
115 */ 146 */
116void __weak arch_jump_label_transform_static(struct jump_entry *entry, 147void __weak __init_or_module arch_jump_label_transform_static(struct jump_entry *entry,
117 enum jump_label_type type) 148 enum jump_label_type type)
118{ 149{
119 arch_jump_label_transform(entry, type); 150 arch_jump_label_transform(entry, type);
@@ -219,8 +250,13 @@ void jump_label_apply_nops(struct module *mod)
219 if (iter_start == iter_stop) 250 if (iter_start == iter_stop)
220 return; 251 return;
221 252
222 for (iter = iter_start; iter < iter_stop; iter++) 253 for (iter = iter_start; iter < iter_stop; iter++) {
223 arch_jump_label_transform_static(iter, JUMP_LABEL_DISABLE); 254 struct jump_label_key *iterk;
255
256 iterk = (struct jump_label_key *)(unsigned long)iter->key;
257 arch_jump_label_transform_static(iter, jump_label_enabled(iterk) ?
258 JUMP_LABEL_ENABLE : JUMP_LABEL_DISABLE);
259 }
224} 260}
225 261
226static int jump_label_add_module(struct module *mod) 262static int jump_label_add_module(struct module *mod)
@@ -260,8 +296,7 @@ static int jump_label_add_module(struct module *mod)
260 key->next = jlm; 296 key->next = jlm;
261 297
262 if (jump_label_enabled(key)) 298 if (jump_label_enabled(key))
263 __jump_label_update(key, iter, iter_stop, 299 __jump_label_update(key, iter, iter_stop, JUMP_LABEL_ENABLE);
264 JUMP_LABEL_ENABLE);
265 } 300 }
266 301
267 return 0; 302 return 0;