summaryrefslogtreecommitdiffstats
path: root/debian/patches-rt/0306-kmemleak-Change-the-lock-of-kmemleak_object-to-raw_s.patch
diff options
context:
space:
mode:
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.patch293
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
+