History

kprobes: Remove kretprobe hash

The kretprobe hash is mostly superfluous, replace it with a per-task variable. This gets rid of the task hash and it's related locking. Note that this may change the kprobes module-exported API for kretprobe handlers. If any out-of-tree kretprobe user uses ri->rp, use get_kretprobe(ri) instead.

Peter Zijlstra committed 6 years ago

Commit d741bf41 parent 476c5815 files · +97 −169Browse files

Unified · Split

5 files
  1. include/linux/kprobes.h +17 −2
  2. include/linux/sched.h +4 −0
  3. kernel/fork.c +4 −0
  4. kernel/kprobes.c +70 −166
  5. kernel/trace/trace_kprobe.c +2 −1
include/linux/kprobes.h+17−2
@@ -27,6 +27,7 @@ · 26 unmodified lines
2727 #include <linux/rcupdate.h>
2828 #include <linux/mutex.h>
2929 #include <linux/ftrace.h>
30+#include <linux/refcount.h>
3031 #include <asm/kprobes.h>
3132
3233 #ifdef CONFIG_KPROBES
@@ -144,6 +145,11 @@ static inline int kprobe_ftrace(struct kprobe *p) · 111 unmodified lines
144145 * ignored, due to maxactive being too low.
145146 *
146147 */
148+struct kretprobe_holder {
149+ struct kretprobe *rp;
150+ refcount_t ref;
151+};
152+
147153 struct kretprobe {
148154 struct kprobe kp;
149155 kretprobe_handler_t handler;
@@ -152,17 +158,18 @@ struct kretprobe { · 2 unmodified lines
152158 int nmissed;
153159 size_t data_size;
154160 struct hlist_head free_instances;
161+ struct kretprobe_holder *rph;
155162 raw_spinlock_t lock;
156163 };
157164
158165 struct kretprobe_instance {
159166 union {
167+ struct llist_node llist;
160168 struct hlist_node hlist;
161169 struct rcu_head rcu;
162170 };
163− struct kretprobe *rp;
171+ struct kretprobe_holder *rph;
164172 kprobe_opcode_t *ret_addr;
165− struct task_struct *task;
166173 void *fp;
167174 char data[];
168175 };
@@ -221,6 +228,14 @@ unsigned long kretprobe_trampoline_handler(struct pt_regs *regs, · 52 unmodified lines
221228 return ret;
222229 }
223230
231+static nokprobe_inline struct kretprobe *get_kretprobe(struct kretprobe_instance *ri)
232+{
233+ RCU_LOCKDEP_WARN(!rcu_read_lock_any_held(),
234+ "Kretprobe is accessed from instance under preemptive context");
235+
236+ return READ_ONCE(ri->rph->rp);
237+}
238+
224239 #else /* CONFIG_KRETPROBES */
225240 static inline void arch_prepare_kretprobe(struct kretprobe *rp,
226241 struct pt_regs *regs)
include/linux/sched.h+4−0
@@ -1315,6 +1315,10 @@ struct task_struct { · 1314 unmodified lines
13151315 struct callback_head mce_kill_me;
13161316 #endif
13171317
1318+#ifdef CONFIG_KRETPROBES
1319+ struct llist_head kretprobe_instances;
1320+#endif
1321+
13181322 /*
13191323 * New fields for task_struct should be added above here, so that
13201324 * they are included in the randomized portion of task_struct.
kernel/fork.c+4−0
@@ -2161,6 +2161,10 @@ static __latent_entropy struct task_struct *copy_process( · 2160 unmodified lines
21612161 INIT_LIST_HEAD(&p->thread_group);
21622162 p->task_works = NULL;
21632163
2164+#ifdef CONFIG_KRETPROBES
2165+ p->kretprobe_instances.first = NULL;
2166+#endif
2167+
21642168 /*
21652169 * Ensure that the cgroup subsystem policies allow the new process to be
21662170 * forked. It should be noted the the new process's css_set can be changed
kernel/kprobes.c+70−166
@@ -53,7 +53,6 @@ static int kprobes_initialized; · 52 unmodified lines
5353 * - RCU hlist traversal under disabling preempt (breakpoint handlers)
5454 */
5555 static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE];
56−static struct hlist_head kretprobe_inst_table[KPROBE_TABLE_SIZE];
5756
5857 /* NOTE: change this value only with kprobe_mutex held */
5958 static bool kprobes_all_disarmed;
@@ -61,9 +60,6 @@ static bool kprobes_all_disarmed; · 1 unmodified line
6160 /* This protects kprobe_table and optimizing_list */
6261 static DEFINE_MUTEX(kprobe_mutex);
6362 static DEFINE_PER_CPU(struct kprobe *, kprobe_instance) = NULL;
64−static struct {
65− raw_spinlock_t lock ____cacheline_aligned_in_smp;
66−} kretprobe_table_locks[KPROBE_TABLE_SIZE];
6763
6864 kprobe_opcode_t * __weak kprobe_lookup_name(const char *name,
6965 unsigned int __unused)
@@ -71,11 +67,6 @@ kprobe_opcode_t * __weak kprobe_lookup_name(const char *name, · 1 unmodified line
7167 return ((kprobe_opcode_t *)(kallsyms_lookup_name(name)));
7268 }
7369
74−static raw_spinlock_t *kretprobe_table_lock_ptr(unsigned long hash)
75−{
76− return &(kretprobe_table_locks[hash].lock);
77−}
78−
7970 /* Blacklist -- list of struct kprobe_blacklist_entry */
8071 static LIST_HEAD(kprobe_blacklist);
8172
@@ -1223,65 +1214,30 @@ void kprobes_inc_nmissed_count(struct kprobe *p) · 1141 unmodified lines
12231214 }
12241215 NOKPROBE_SYMBOL(kprobes_inc_nmissed_count);
12251216
1217+static void free_rp_inst_rcu(struct rcu_head *head)
1218+{
1219+ struct kretprobe_instance *ri = container_of(head, struct kretprobe_instance, rcu);
1220+
1221+ if (refcount_dec_and_test(&ri->rph->ref))
1222+ kfree(ri->rph);
1223+ kfree(ri);
1224+}
1225+NOKPROBE_SYMBOL(free_rp_inst_rcu);
1226+
12261227 static void recycle_rp_inst(struct kretprobe_instance *ri)
12271228 {
1228− struct kretprobe *rp = ri->rp;
1229+ struct kretprobe *rp = get_kretprobe(ri);
12291230
1230− /* remove rp inst off the rprobe_inst_table */
1231− hlist_del(&ri->hlist);
12321231 INIT_HLIST_NODE(&ri->hlist);
12331232 if (likely(rp)) {
12341233 raw_spin_lock(&rp->lock);
12351234 hlist_add_head(&ri->hlist, &rp->free_instances);
12361235 raw_spin_unlock(&rp->lock);
12371236 } else
1238− kfree_rcu(ri, rcu);
1237+ call_rcu(&ri->rcu, free_rp_inst_rcu);
12391238 }
12401239 NOKPROBE_SYMBOL(recycle_rp_inst);
12411240
1242−static void kretprobe_hash_lock(struct task_struct *tsk,
1243− struct hlist_head **head, unsigned long *flags)
1244−__acquires(hlist_lock)
1245−{
1246− unsigned long hash = hash_ptr(tsk, KPROBE_HASH_BITS);
1247− raw_spinlock_t *hlist_lock;
1248−
1249− *head = &kretprobe_inst_table[hash];
1250− hlist_lock = kretprobe_table_lock_ptr(hash);
1251− raw_spin_lock_irqsave(hlist_lock, *flags);
1252−}
1253−NOKPROBE_SYMBOL(kretprobe_hash_lock);
1254−
1255−static void kretprobe_table_lock(unsigned long hash,
1256− unsigned long *flags)
1257−__acquires(hlist_lock)
1258−{
1259− raw_spinlock_t *hlist_lock = kretprobe_table_lock_ptr(hash);
1260− raw_spin_lock_irqsave(hlist_lock, *flags);
1261−}
1262−NOKPROBE_SYMBOL(kretprobe_table_lock);
1263−
1264−static void kretprobe_hash_unlock(struct task_struct *tsk,
1265− unsigned long *flags)
1266−__releases(hlist_lock)
1267−{
1268− unsigned long hash = hash_ptr(tsk, KPROBE_HASH_BITS);
1269− raw_spinlock_t *hlist_lock;
1270−
1271− hlist_lock = kretprobe_table_lock_ptr(hash);
1272− raw_spin_unlock_irqrestore(hlist_lock, *flags);
1273−}
1274−NOKPROBE_SYMBOL(kretprobe_hash_unlock);
1275−
1276−static void kretprobe_table_unlock(unsigned long hash,
1277− unsigned long *flags)
1278−__releases(hlist_lock)
1279−{
1280− raw_spinlock_t *hlist_lock = kretprobe_table_lock_ptr(hash);
1281− raw_spin_unlock_irqrestore(hlist_lock, *flags);
1282−}
1283−NOKPROBE_SYMBOL(kretprobe_table_unlock);
1284−
12851241 static struct kprobe kprobe_busy = {
12861242 .addr = (void *) get_kprobe,
12871243 };
@@ -1311,24 +1267,21 @@ void kprobe_busy_end(void) · 23 unmodified lines
13111267 void kprobe_flush_task(struct task_struct *tk)
13121268 {
13131269 struct kretprobe_instance *ri;
1314− struct hlist_head *head;
1315− struct hlist_node *tmp;
1316− unsigned long hash, flags = 0;
1270+ struct llist_node *node;
13171271
1272+ /* Early boot, not yet initialized. */
13181273 if (unlikely(!kprobes_initialized))
1319− /* Early boot. kretprobe_table_locks not yet initialized. */
13201274 return;
13211275
13221276 kprobe_busy_begin();
13231277
1324− hash = hash_ptr(tk, KPROBE_HASH_BITS);
1325− head = &kretprobe_inst_table[hash];
1326− kretprobe_table_lock(hash, &flags);
1327− hlist_for_each_entry_safe(ri, tmp, head, hlist) {
1328− if (ri->task == tk)
1329− recycle_rp_inst(ri);
1278+ node = __llist_del_all(&tk->kretprobe_instances);
1279+ while (node) {
1280+ ri = container_of(node, struct kretprobe_instance, llist);
1281+ node = node->next;
1282+
1283+ recycle_rp_inst(ri);
13301284 }
1331− kretprobe_table_unlock(hash, &flags);
13321285
13331286 kprobe_busy_end();
13341287 }
@@ -1338,36 +1291,19 @@ static inline void free_rp_inst(struct kretprobe *rp) · 3 unmodified lines
13381291 {
13391292 struct kretprobe_instance *ri;
13401293 struct hlist_node *next;
1294+ int count = 0;
13411295
13421296 hlist_for_each_entry_safe(ri, next, &rp->free_instances, hlist) {
13431297 hlist_del(&ri->hlist);
13441298 kfree(ri);
1299+ count++;
13451300 }
1346−}
1347−
1348−static void cleanup_rp_inst(struct kretprobe *rp)
1349−{
1350− unsigned long flags, hash;
1351− struct kretprobe_instance *ri;
1352− struct hlist_node *next;
1353− struct hlist_head *head;
13541301
1355− /* To avoid recursive kretprobe by NMI, set kprobe busy here */
1356− kprobe_busy_begin();
1357− for (hash = 0; hash < KPROBE_TABLE_SIZE; hash++) {
1358− kretprobe_table_lock(hash, &flags);
1359− head = &kretprobe_inst_table[hash];
1360− hlist_for_each_entry_safe(ri, next, head, hlist) {
1361− if (ri->rp == rp)
1362− ri->rp = NULL;
1363− }
1364− kretprobe_table_unlock(hash, &flags);
1302+ if (refcount_sub_and_test(count, &rp->rph->ref)) {
1303+ kfree(rp->rph);
1304+ rp->rph = NULL;
13651305 }
1366− kprobe_busy_end();
1367−
1368− free_rp_inst(rp);
13691306 }
1370−NOKPROBE_SYMBOL(cleanup_rp_inst);
13711307
13721308 /* Add the new probe to ap->list */
13731309 static int add_new_kprobe(struct kprobe *ap, struct kprobe *p)
@@ -1928,88 +1864,56 @@ unsigned long __kretprobe_trampoline_handler(struct pt_regs *regs, · 554 unmodified lines
19281864 void *trampoline_address,
19291865 void *frame_pointer)
19301866 {
1931− struct kretprobe_instance *ri = NULL, *last = NULL;
1932− struct hlist_head *head;
1933− struct hlist_node *tmp;
1934− unsigned long flags;
19351867 kprobe_opcode_t *correct_ret_addr = NULL;
1936− bool skipped = false;
1868+ struct kretprobe_instance *ri = NULL;
1869+ struct llist_node *first, *node;
1870+ struct kretprobe *rp;
19371871
1938− kretprobe_hash_lock(current, &head, &flags);
1872+ /* Find all nodes for this frame. */
1873+ first = node = current->kretprobe_instances.first;
1874+ while (node) {
1875+ ri = container_of(node, struct kretprobe_instance, llist);
19391876
1940− /*
1941− * It is possible to have multiple instances associated with a given
1942− * task either because multiple functions in the call path have
1943− * return probes installed on them, and/or more than one
1944− * return probe was registered for a target function.
1945− *
1946− * We can handle this because:
1947− * - instances are always pushed into the head of the list
1948− * - when multiple return probes are registered for the same
1949− * function, the (chronologically) first instance's ret_addr
1950− * will be the real return address, and all the rest will
1951− * point to kretprobe_trampoline.
1952− */
1953− hlist_for_each_entry(ri, head, hlist) {
1954− if (ri->task != current)
1955− /* another task is sharing our hash bucket */
1956− continue;
1957− /*
1958− * Return probes must be pushed on this hash list correct
1959− * order (same as return order) so that it can be popped
1960− * correctly. However, if we find it is pushed it incorrect
1961− * order, this means we find a function which should not be
1962− * probed, because the wrong order entry is pushed on the
1963− * path of processing other kretprobe itself.
1964− */
1965− if (ri->fp != frame_pointer) {
1966− if (!skipped)
1967− pr_warn("kretprobe is stacked incorrectly. Trying to fixup.\n");
1968− skipped = true;
1969− continue;
1970− }
1877+ BUG_ON(ri->fp != frame_pointer);
19711878
1972− correct_ret_addr = ri->ret_addr;
1973− if (skipped)
1974− pr_warn("%ps must be blacklisted because of incorrect kretprobe order\n",
1975− ri->rp->kp.addr);
1976−
1977− if (correct_ret_addr != trampoline_address)
1879+ if (ri->ret_addr != trampoline_address) {
1880+ correct_ret_addr = ri->ret_addr;
19781881 /*
19791882 * This is the real return address. Any other
19801883 * instances associated with this task are for
19811884 * other calls deeper on the call stack
19821885 */
1983− break;
1886+ goto found;
1887+ }
1888+
1889+ node = node->next;
19841890 }
1891+ pr_err("Oops! Kretprobe fails to find correct return address.\n");
1892+ BUG_ON(1);
19851893
1986− BUG_ON(!correct_ret_addr || (correct_ret_addr == trampoline_address));
1987− last = ri;
1894+found:
1895+ /* Unlink all nodes for this frame. */
1896+ current->kretprobe_instances.first = node->next;
1897+ node->next = NULL;
19881898
1989− hlist_for_each_entry_safe(ri, tmp, head, hlist) {
1990− if (ri->task != current)
1991− /* another task is sharing our hash bucket */
1992− continue;
1993− if (ri->fp != frame_pointer)
1994− continue;
1899+ /* Run them.. */
1900+ while (first) {
1901+ ri = container_of(first, struct kretprobe_instance, llist);
1902+ first = first->next;
19951903
1996− if (ri->rp && ri->rp->handler) {
1904+ rp = get_kretprobe(ri);
1905+ if (rp && rp->handler) {
19971906 struct kprobe *prev = kprobe_running();
19981907
1999− __this_cpu_write(current_kprobe, &ri->rp->kp);
1908+ __this_cpu_write(current_kprobe, &rp->kp);
20001909 ri->ret_addr = correct_ret_addr;
2001− ri->rp->handler(ri, regs);
1910+ rp->handler(ri, regs);
20021911 __this_cpu_write(current_kprobe, prev);
20031912 }
20041913
20051914 recycle_rp_inst(ri);
2006−
2007− if (ri == last)
2008− break;
20091915 }
20101916
2011− kretprobe_hash_unlock(current, &flags);
2012−
20131917 return (unsigned long)correct_ret_addr;
20141918 }
20151919 NOKPROBE_SYMBOL(__kretprobe_trampoline_handler)
@@ -2021,11 +1925,10 @@ NOKPROBE_SYMBOL(__kretprobe_trampoline_handler) · 5 unmodified lines
20211925 static int pre_handler_kretprobe(struct kprobe *p, struct pt_regs *regs)
20221926 {
20231927 struct kretprobe *rp = container_of(p, struct kretprobe, kp);
2024− unsigned long hash, flags = 0;
1928+ unsigned long flags = 0;
20251929 struct kretprobe_instance *ri;
20261930
20271931 /* TODO: consider to only swap the RA after the last pre_handler fired */
2028− hash = hash_ptr(current, KPROBE_HASH_BITS);
20291932 raw_spin_lock_irqsave(&rp->lock, flags);
20301933 if (!hlist_empty(&rp->free_instances)) {
20311934 ri = hlist_entry(rp->free_instances.first,
@@ -2033,9 +1936,6 @@ static int pre_handler_kretprobe(struct kprobe *p, struct pt_regs *regs) · 1 unmodified line
20331936 hlist_del(&ri->hlist);
20341937 raw_spin_unlock_irqrestore(&rp->lock, flags);
20351938
2036− ri->rp = rp;
2037− ri->task = current;
2038−
20391939 if (rp->entry_handler && rp->entry_handler(ri, regs)) {
20401940 raw_spin_lock_irqsave(&rp->lock, flags);
20411941 hlist_add_head(&ri->hlist, &rp->free_instances);
@@ -2045,11 +1945,8 @@ static int pre_handler_kretprobe(struct kprobe *p, struct pt_regs *regs) · 3 unmodified lines
20451945
20461946 arch_prepare_kretprobe(ri, regs);
20471947
2048− /* XXX(hch): why is there no hlist_move_head? */
2049− INIT_HLIST_NODE(&ri->hlist);
2050− kretprobe_table_lock(hash, &flags);
2051− hlist_add_head(&ri->hlist, &kretprobe_inst_table[hash]);
2052− kretprobe_table_unlock(hash, &flags);
1948+ __llist_add(&ri->llist, &current->kretprobe_instances);
1949+
20531950 } else {
20541951 rp->nmissed++;
20551952 raw_spin_unlock_irqrestore(&rp->lock, flags);
@@ -2112,16 +2009,24 @@ int register_kretprobe(struct kretprobe *rp) · 56 unmodified lines
21122009 }
21132010 raw_spin_lock_init(&rp->lock);
21142011 INIT_HLIST_HEAD(&rp->free_instances);
2012+ rp->rph = kzalloc(sizeof(struct kretprobe_holder), GFP_KERNEL);
2013+ if (!rp->rph)
2014+ return -ENOMEM;
2015+
2016+ rp->rph->rp = rp;
21152017 for (i = 0; i < rp->maxactive; i++) {
2116− inst = kmalloc(sizeof(struct kretprobe_instance) +
2018+ inst = kzalloc(sizeof(struct kretprobe_instance) +
21172019 rp->data_size, GFP_KERNEL);
21182020 if (inst == NULL) {
2021+ refcount_set(&rp->rph->ref, i);
21192022 free_rp_inst(rp);
21202023 return -ENOMEM;
21212024 }
2025+ inst->rph = rp->rph;
21222026 INIT_HLIST_NODE(&inst->hlist);
21232027 hlist_add_head(&inst->hlist, &rp->free_instances);
21242028 }
2029+ refcount_set(&rp->rph->ref, i);
21252030
21262031 rp->nmissed = 0;
21272032 /* Establish function entry probe point */
@@ -2163,16 +2068,18 @@ void unregister_kretprobes(struct kretprobe **rps, int num) · 35 unmodified lines
21632068 if (num <= 0)
21642069 return;
21652070 mutex_lock(&kprobe_mutex);
2166− for (i = 0; i < num; i++)
2071+ for (i = 0; i < num; i++) {
21672072 if (__unregister_kprobe_top(&rps[i]->kp) < 0)
21682073 rps[i]->kp.addr = NULL;
2074+ rps[i]->rph->rp = NULL;
2075+ }
21692076 mutex_unlock(&kprobe_mutex);
21702077
21712078 synchronize_rcu();
21722079 for (i = 0; i < num; i++) {
21732080 if (rps[i]->kp.addr) {
21742081 __unregister_kprobe_bottom(&rps[i]->kp);
2175− cleanup_rp_inst(rps[i]);
2082+ free_rp_inst(rps[i]);
21762083 }
21772084 }
21782085 }
@@ -2535,11 +2442,8 @@ static int __init init_kprobes(void) · 356 unmodified lines
25352442
25362443 /* FIXME allocate the probe table, currently defined statically */
25372444 /* initialize all list heads */
2538− for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
2445+ for (i = 0; i < KPROBE_TABLE_SIZE; i++)
25392446 INIT_HLIST_HEAD(&kprobe_table[i]);
2540− INIT_HLIST_HEAD(&kretprobe_inst_table[i]);
2541− raw_spin_lock_init(&(kretprobe_table_locks[i].lock));
2542− }
25432447
25442448 err = populate_kprobe_blacklist(__start_kprobe_blacklist,
25452449 __stop_kprobe_blacklist);
kernel/trace/trace_kprobe.c+2−1
@@ -1714,7 +1714,8 @@ NOKPROBE_SYMBOL(kprobe_dispatcher); · 1713 unmodified lines
17141714 static int
17151715 kretprobe_dispatcher(struct kretprobe_instance *ri, struct pt_regs *regs)
17161716 {
1717− struct trace_kprobe *tk = container_of(ri->rp, struct trace_kprobe, rp);
1717+ struct kretprobe *rp = get_kretprobe(ri);
1718+ struct trace_kprobe *tk = container_of(rp, struct trace_kprobe, rp);
17181719
17191720 raw_cpu_inc(*tk->nhit);
17201721

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t