Allen Martin | 685e0f8 | 2016-07-26 19:34:29 -0700 | [diff] [blame^] | 1 | From 25dcf30c87ef9eb5ec60063eabfdfebdaa47b107 Mon Sep 17 00:00:00 2001 |
| 2 | From: Thomas Gleixner <tglx@linutronix.de> |
| 3 | Date: Sun, 17 Jul 2011 21:33:18 +0200 |
| 4 | Subject: [PATCH 115/317] radix-tree: Make RT aware |
| 5 | X-NVConfidentiality: public |
| 6 | |
| 7 | Disable radix_tree_preload() on -RT. This functions returns with |
| 8 | preemption disabled which may cause high latencies and breaks if the |
| 9 | user tries to grab any locks after invoking it. |
| 10 | |
| 11 | Signed-off-by: Thomas Gleixner <tglx@linutronix.de> |
| 12 | Signed-off-by: Allen Martin <amartin@nvidia.com> |
| 13 | --- |
| 14 | include/linux/radix-tree.h | 7 ++++++- |
| 15 | lib/radix-tree.c | 5 ++++- |
| 16 | 2 files changed, 10 insertions(+), 2 deletions(-) |
| 17 | |
| 18 | diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h |
| 19 | index 5d5174b59802..8ddbd6e15a3c 100644 |
| 20 | --- a/include/linux/radix-tree.h |
| 21 | +++ b/include/linux/radix-tree.h |
| 22 | @@ -277,8 +277,13 @@ radix_tree_gang_lookup(struct radix_tree_root *root, void **results, |
| 23 | unsigned int radix_tree_gang_lookup_slot(struct radix_tree_root *root, |
| 24 | void ***results, unsigned long *indices, |
| 25 | unsigned long first_index, unsigned int max_items); |
| 26 | +#ifndef CONFIG_PREEMPT_RT_FULL |
| 27 | int radix_tree_preload(gfp_t gfp_mask); |
| 28 | int radix_tree_maybe_preload(gfp_t gfp_mask); |
| 29 | +#else |
| 30 | +static inline int radix_tree_preload(gfp_t gm) { return 0; } |
| 31 | +static inline int radix_tree_maybe_preload(gfp_t gfp_mask) { return 0; } |
| 32 | +#endif |
| 33 | void radix_tree_init(void); |
| 34 | void *radix_tree_tag_set(struct radix_tree_root *root, |
| 35 | unsigned long index, unsigned int tag); |
| 36 | @@ -303,7 +308,7 @@ unsigned long radix_tree_locate_item(struct radix_tree_root *root, void *item); |
| 37 | |
| 38 | static inline void radix_tree_preload_end(void) |
| 39 | { |
| 40 | - preempt_enable(); |
| 41 | + preempt_enable_nort(); |
| 42 | } |
| 43 | |
| 44 | /** |
| 45 | diff --git a/lib/radix-tree.c b/lib/radix-tree.c |
| 46 | index 6b79e9026e24..f27e0bcb74f7 100644 |
| 47 | --- a/lib/radix-tree.c |
| 48 | +++ b/lib/radix-tree.c |
| 49 | @@ -196,13 +196,14 @@ radix_tree_node_alloc(struct radix_tree_root *root) |
| 50 | * succeed in getting a node here (and never reach |
| 51 | * kmem_cache_alloc) |
| 52 | */ |
| 53 | - rtp = this_cpu_ptr(&radix_tree_preloads); |
| 54 | + rtp = &get_cpu_var(radix_tree_preloads); |
| 55 | if (rtp->nr) { |
| 56 | ret = rtp->nodes; |
| 57 | rtp->nodes = ret->private_data; |
| 58 | ret->private_data = NULL; |
| 59 | rtp->nr--; |
| 60 | } |
| 61 | + put_cpu_var(radix_tree_preloads); |
| 62 | /* |
| 63 | * Update the allocation stack trace as this is more useful |
| 64 | * for debugging. |
| 65 | @@ -242,6 +243,7 @@ radix_tree_node_free(struct radix_tree_node *node) |
| 66 | call_rcu(&node->rcu_head, radix_tree_node_rcu_free); |
| 67 | } |
| 68 | |
| 69 | +#ifndef CONFIG_PREEMPT_RT_FULL |
| 70 | /* |
| 71 | * Load up this CPU's radix_tree_node buffer with sufficient objects to |
| 72 | * ensure that the addition of a single element in the tree cannot fail. On |
| 73 | @@ -310,6 +312,7 @@ int radix_tree_maybe_preload(gfp_t gfp_mask) |
| 74 | return 0; |
| 75 | } |
| 76 | EXPORT_SYMBOL(radix_tree_maybe_preload); |
| 77 | +#endif |
| 78 | |
| 79 | /* |
| 80 | * Return the maximum key which can be store into a |
| 81 | -- |
| 82 | 2.9.3 |
| 83 | |