diff options
Diffstat (limited to 'debian/patches-rt/0306-kmemleak-Change-the-lock-of-kmemleak_object-to-raw_s.patch')
-rw-r--r-- | debian/patches-rt/0306-kmemleak-Change-the-lock-of-kmemleak_object-to-raw_s.patch | 293 |
1 files changed, 293 insertions, 0 deletions
diff --git a/debian/patches-rt/0306-kmemleak-Change-the-lock-of-kmemleak_object-to-raw_s.patch b/debian/patches-rt/0306-kmemleak-Change-the-lock-of-kmemleak_object-to-raw_s.patch new file mode 100644 index 000000000..ca08e2aca --- /dev/null +++ b/debian/patches-rt/0306-kmemleak-Change-the-lock-of-kmemleak_object-to-raw_s.patch @@ -0,0 +1,293 @@ +From 3d72712c05917c06303670565d51a308334595d6 Mon Sep 17 00:00:00 2001 +From: Liu Haitao <haitao.liu@windriver.com> +Date: Fri, 27 Sep 2019 16:22:30 +0800 +Subject: [PATCH 306/347] kmemleak: Change the lock of kmemleak_object to + raw_spinlock_t +Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/4.19/older/patches-4.19.246-rt110.tar.xz + +[ Upstream commit 217847f57119b5fdd377bfa3d344613ddb98d9fc ] + +The commit ("kmemleak: Turn kmemleak_lock to raw spinlock on RT") +changed the kmemleak_lock to raw spinlock. However the +kmemleak_object->lock is held after the kmemleak_lock is held in +scan_block(). + +Make the object->lock a raw_spinlock_t. + +Cc: stable-rt@vger.kernel.org +Link: https://lkml.kernel.org/r/20190927082230.34152-1-yongxin.liu@windriver.com +Signed-off-by: Liu Haitao <haitao.liu@windriver.com> +Signed-off-by: Yongxin Liu <yongxin.liu@windriver.com> +Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> +Signed-off-by: Steven Rostedt (VMware) <rostedt@goodmis.org> +--- + mm/kmemleak.c | 72 +++++++++++++++++++++++++-------------------------- + 1 file changed, 36 insertions(+), 36 deletions(-) + +diff --git a/mm/kmemleak.c b/mm/kmemleak.c +index 5b6718dd3a64..23e2837501d6 100644 +--- a/mm/kmemleak.c ++++ b/mm/kmemleak.c +@@ -147,7 +147,7 @@ struct kmemleak_scan_area { + * (use_count) and freed using the RCU mechanism. + */ + struct kmemleak_object { +- spinlock_t lock; ++ raw_spinlock_t lock; + unsigned int flags; /* object status flags */ + struct list_head object_list; + struct list_head gray_list; +@@ -561,7 +561,7 @@ static struct kmemleak_object *create_object(unsigned long ptr, size_t size, + INIT_LIST_HEAD(&object->object_list); + INIT_LIST_HEAD(&object->gray_list); + INIT_HLIST_HEAD(&object->area_list); +- spin_lock_init(&object->lock); ++ raw_spin_lock_init(&object->lock); + atomic_set(&object->use_count, 1); + object->flags = OBJECT_ALLOCATED; + object->pointer = ptr; +@@ -642,9 +642,9 @@ static void __delete_object(struct kmemleak_object *object) + * Locking here also ensures that the corresponding memory block + * cannot be freed when it is being scanned. + */ +- spin_lock_irqsave(&object->lock, flags); ++ raw_spin_lock_irqsave(&object->lock, flags); + object->flags &= ~OBJECT_ALLOCATED; +- spin_unlock_irqrestore(&object->lock, flags); ++ raw_spin_unlock_irqrestore(&object->lock, flags); + put_object(object); + } + +@@ -716,9 +716,9 @@ static void paint_it(struct kmemleak_object *object, int color) + { + unsigned long flags; + +- spin_lock_irqsave(&object->lock, flags); ++ raw_spin_lock_irqsave(&object->lock, flags); + __paint_it(object, color); +- spin_unlock_irqrestore(&object->lock, flags); ++ raw_spin_unlock_irqrestore(&object->lock, flags); + } + + static void paint_ptr(unsigned long ptr, int color) +@@ -778,7 +778,7 @@ static void add_scan_area(unsigned long ptr, size_t size, gfp_t gfp) + goto out; + } + +- spin_lock_irqsave(&object->lock, flags); ++ raw_spin_lock_irqsave(&object->lock, flags); + if (size == SIZE_MAX) { + size = object->pointer + object->size - ptr; + } else if (ptr + size > object->pointer + object->size) { +@@ -794,7 +794,7 @@ static void add_scan_area(unsigned long ptr, size_t size, gfp_t gfp) + + hlist_add_head(&area->node, &object->area_list); + out_unlock: +- spin_unlock_irqrestore(&object->lock, flags); ++ raw_spin_unlock_irqrestore(&object->lock, flags); + out: + put_object(object); + } +@@ -817,9 +817,9 @@ static void object_set_excess_ref(unsigned long ptr, unsigned long excess_ref) + return; + } + +- spin_lock_irqsave(&object->lock, flags); ++ raw_spin_lock_irqsave(&object->lock, flags); + object->excess_ref = excess_ref; +- spin_unlock_irqrestore(&object->lock, flags); ++ raw_spin_unlock_irqrestore(&object->lock, flags); + put_object(object); + } + +@@ -839,9 +839,9 @@ static void object_no_scan(unsigned long ptr) + return; + } + +- spin_lock_irqsave(&object->lock, flags); ++ raw_spin_lock_irqsave(&object->lock, flags); + object->flags |= OBJECT_NO_SCAN; +- spin_unlock_irqrestore(&object->lock, flags); ++ raw_spin_unlock_irqrestore(&object->lock, flags); + put_object(object); + } + +@@ -902,11 +902,11 @@ static void early_alloc(struct early_log *log) + log->min_count, GFP_ATOMIC); + if (!object) + goto out; +- spin_lock_irqsave(&object->lock, flags); ++ raw_spin_lock_irqsave(&object->lock, flags); + for (i = 0; i < log->trace_len; i++) + object->trace[i] = log->trace[i]; + object->trace_len = log->trace_len; +- spin_unlock_irqrestore(&object->lock, flags); ++ raw_spin_unlock_irqrestore(&object->lock, flags); + out: + rcu_read_unlock(); + } +@@ -1096,9 +1096,9 @@ void __ref kmemleak_update_trace(const void *ptr) + return; + } + +- spin_lock_irqsave(&object->lock, flags); ++ raw_spin_lock_irqsave(&object->lock, flags); + object->trace_len = __save_stack_trace(object->trace); +- spin_unlock_irqrestore(&object->lock, flags); ++ raw_spin_unlock_irqrestore(&object->lock, flags); + + put_object(object); + } +@@ -1344,7 +1344,7 @@ static void scan_block(void *_start, void *_end, + * previously acquired in scan_object(). These locks are + * enclosed by scan_mutex. + */ +- spin_lock_nested(&object->lock, SINGLE_DEPTH_NESTING); ++ raw_spin_lock_nested(&object->lock, SINGLE_DEPTH_NESTING); + /* only pass surplus references (object already gray) */ + if (color_gray(object)) { + excess_ref = object->excess_ref; +@@ -1353,7 +1353,7 @@ static void scan_block(void *_start, void *_end, + excess_ref = 0; + update_refs(object); + } +- spin_unlock(&object->lock); ++ raw_spin_unlock(&object->lock); + + if (excess_ref) { + object = lookup_object(excess_ref, 0); +@@ -1362,9 +1362,9 @@ static void scan_block(void *_start, void *_end, + if (object == scanned) + /* circular reference, ignore */ + continue; +- spin_lock_nested(&object->lock, SINGLE_DEPTH_NESTING); ++ raw_spin_lock_nested(&object->lock, SINGLE_DEPTH_NESTING); + update_refs(object); +- spin_unlock(&object->lock); ++ raw_spin_unlock(&object->lock); + } + } + raw_spin_unlock_irqrestore(&kmemleak_lock, flags); +@@ -1400,7 +1400,7 @@ static void scan_object(struct kmemleak_object *object) + * Once the object->lock is acquired, the corresponding memory block + * cannot be freed (the same lock is acquired in delete_object). + */ +- spin_lock_irqsave(&object->lock, flags); ++ raw_spin_lock_irqsave(&object->lock, flags); + if (object->flags & OBJECT_NO_SCAN) + goto out; + if (!(object->flags & OBJECT_ALLOCATED)) +@@ -1419,9 +1419,9 @@ static void scan_object(struct kmemleak_object *object) + if (start >= end) + break; + +- spin_unlock_irqrestore(&object->lock, flags); ++ raw_spin_unlock_irqrestore(&object->lock, flags); + cond_resched(); +- spin_lock_irqsave(&object->lock, flags); ++ raw_spin_lock_irqsave(&object->lock, flags); + } while (object->flags & OBJECT_ALLOCATED); + } else + hlist_for_each_entry(area, &object->area_list, node) +@@ -1429,7 +1429,7 @@ static void scan_object(struct kmemleak_object *object) + (void *)(area->start + area->size), + object); + out: +- spin_unlock_irqrestore(&object->lock, flags); ++ raw_spin_unlock_irqrestore(&object->lock, flags); + } + + /* +@@ -1482,7 +1482,7 @@ static void kmemleak_scan(void) + /* prepare the kmemleak_object's */ + rcu_read_lock(); + list_for_each_entry_rcu(object, &object_list, object_list) { +- spin_lock_irqsave(&object->lock, flags); ++ raw_spin_lock_irqsave(&object->lock, flags); + #ifdef DEBUG + /* + * With a few exceptions there should be a maximum of +@@ -1499,7 +1499,7 @@ static void kmemleak_scan(void) + if (color_gray(object) && get_object(object)) + list_add_tail(&object->gray_list, &gray_list); + +- spin_unlock_irqrestore(&object->lock, flags); ++ raw_spin_unlock_irqrestore(&object->lock, flags); + } + rcu_read_unlock(); + +@@ -1564,14 +1564,14 @@ static void kmemleak_scan(void) + */ + rcu_read_lock(); + list_for_each_entry_rcu(object, &object_list, object_list) { +- spin_lock_irqsave(&object->lock, flags); ++ raw_spin_lock_irqsave(&object->lock, flags); + if (color_white(object) && (object->flags & OBJECT_ALLOCATED) + && update_checksum(object) && get_object(object)) { + /* color it gray temporarily */ + object->count = object->min_count; + list_add_tail(&object->gray_list, &gray_list); + } +- spin_unlock_irqrestore(&object->lock, flags); ++ raw_spin_unlock_irqrestore(&object->lock, flags); + } + rcu_read_unlock(); + +@@ -1591,13 +1591,13 @@ static void kmemleak_scan(void) + */ + rcu_read_lock(); + list_for_each_entry_rcu(object, &object_list, object_list) { +- spin_lock_irqsave(&object->lock, flags); ++ raw_spin_lock_irqsave(&object->lock, flags); + if (unreferenced_object(object) && + !(object->flags & OBJECT_REPORTED)) { + object->flags |= OBJECT_REPORTED; + new_leaks++; + } +- spin_unlock_irqrestore(&object->lock, flags); ++ raw_spin_unlock_irqrestore(&object->lock, flags); + } + rcu_read_unlock(); + +@@ -1749,10 +1749,10 @@ static int kmemleak_seq_show(struct seq_file *seq, void *v) + struct kmemleak_object *object = v; + unsigned long flags; + +- spin_lock_irqsave(&object->lock, flags); ++ raw_spin_lock_irqsave(&object->lock, flags); + if ((object->flags & OBJECT_REPORTED) && unreferenced_object(object)) + print_unreferenced(seq, object); +- spin_unlock_irqrestore(&object->lock, flags); ++ raw_spin_unlock_irqrestore(&object->lock, flags); + return 0; + } + +@@ -1782,9 +1782,9 @@ static int dump_str_object_info(const char *str) + return -EINVAL; + } + +- spin_lock_irqsave(&object->lock, flags); ++ raw_spin_lock_irqsave(&object->lock, flags); + dump_object_info(object); +- spin_unlock_irqrestore(&object->lock, flags); ++ raw_spin_unlock_irqrestore(&object->lock, flags); + + put_object(object); + return 0; +@@ -1803,11 +1803,11 @@ static void kmemleak_clear(void) + + rcu_read_lock(); + list_for_each_entry_rcu(object, &object_list, object_list) { +- spin_lock_irqsave(&object->lock, flags); ++ raw_spin_lock_irqsave(&object->lock, flags); + if ((object->flags & OBJECT_REPORTED) && + unreferenced_object(object)) + __paint_it(object, KMEMLEAK_GREY); +- spin_unlock_irqrestore(&object->lock, flags); ++ raw_spin_unlock_irqrestore(&object->lock, flags); + } + rcu_read_unlock(); + +-- +2.36.1 + |