summaryrefslogtreecommitdiffstats
path: root/debian/patches-rt/futex-Delay-deallocation-of-pi_state.patch
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches-rt/futex-Delay-deallocation-of-pi_state.patch')
-rw-r--r--debian/patches-rt/futex-Delay-deallocation-of-pi_state.patch174
1 files changed, 0 insertions, 174 deletions
diff --git a/debian/patches-rt/futex-Delay-deallocation-of-pi_state.patch b/debian/patches-rt/futex-Delay-deallocation-of-pi_state.patch
deleted file mode 100644
index 507a015a3..000000000
--- a/debian/patches-rt/futex-Delay-deallocation-of-pi_state.patch
+++ /dev/null
@@ -1,174 +0,0 @@
-From: Thomas Gleixner <tglx@linutronix.de>
-Date: Wed, 26 Jun 2019 13:35:36 +0200
-Subject: [PATCH] futex: Delay deallocation of pi_state
-Origin: https://www.kernel.org/pub/linux/kernel/projects/rt/5.2/older/patches-5.2.17-rt9.tar.xz
-
-On -RT we can't invoke kfree() in a non-preemptible context.
-
-Defer the deallocation of pi_state to preemptible context.
-
-Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
-Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
----
- kernel/futex.c | 55 ++++++++++++++++++++++++++++++++++++++++++++-----------
- 1 file changed, 44 insertions(+), 11 deletions(-)
-
---- a/kernel/futex.c
-+++ b/kernel/futex.c
-@@ -814,13 +814,13 @@ static void get_pi_state(struct futex_pi
- * Drops a reference to the pi_state object and frees or caches it
- * when the last reference is gone.
- */
--static void put_pi_state(struct futex_pi_state *pi_state)
-+static struct futex_pi_state *__put_pi_state(struct futex_pi_state *pi_state)
- {
- if (!pi_state)
-- return;
-+ return NULL;
-
- if (!refcount_dec_and_test(&pi_state->refcount))
-- return;
-+ return NULL;
-
- /*
- * If pi_state->owner is NULL, the owner is most probably dying
-@@ -840,9 +840,7 @@ static void put_pi_state(struct futex_pi
- raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock);
- }
-
-- if (current->pi_state_cache) {
-- kfree(pi_state);
-- } else {
-+ if (!current->pi_state_cache) {
- /*
- * pi_state->list is already empty.
- * clear pi_state->owner.
-@@ -851,6 +849,30 @@ static void put_pi_state(struct futex_pi
- pi_state->owner = NULL;
- refcount_set(&pi_state->refcount, 1);
- current->pi_state_cache = pi_state;
-+ pi_state = NULL;
-+ }
-+ return pi_state;
-+}
-+
-+static void put_pi_state(struct futex_pi_state *pi_state)
-+{
-+ kfree(__put_pi_state(pi_state));
-+}
-+
-+static void put_pi_state_atomic(struct futex_pi_state *pi_state,
-+ struct list_head *to_free)
-+{
-+ if (__put_pi_state(pi_state))
-+ list_add(&pi_state->list, to_free);
-+}
-+
-+static void free_pi_state_list(struct list_head *to_free)
-+{
-+ struct futex_pi_state *p, *next;
-+
-+ list_for_each_entry_safe(p, next, to_free, list) {
-+ list_del(&p->list);
-+ kfree(p);
- }
- }
-
-@@ -867,6 +889,7 @@ void exit_pi_state_list(struct task_stru
- struct futex_pi_state *pi_state;
- struct futex_hash_bucket *hb;
- union futex_key key = FUTEX_KEY_INIT;
-+ LIST_HEAD(to_free);
-
- if (!futex_cmpxchg_enabled)
- return;
-@@ -911,7 +934,7 @@ void exit_pi_state_list(struct task_stru
- /* retain curr->pi_lock for the loop invariant */
- raw_spin_unlock(&pi_state->pi_mutex.wait_lock);
- raw_spin_unlock(&hb->lock);
-- put_pi_state(pi_state);
-+ put_pi_state_atomic(pi_state, &to_free);
- continue;
- }
-
-@@ -930,6 +953,8 @@ void exit_pi_state_list(struct task_stru
- raw_spin_lock_irq(&curr->pi_lock);
- }
- raw_spin_unlock_irq(&curr->pi_lock);
-+
-+ free_pi_state_list(&to_free);
- }
-
- #endif
-@@ -1910,6 +1935,7 @@ static int futex_requeue(u32 __user *uad
- struct futex_hash_bucket *hb1, *hb2;
- struct futex_q *this, *next;
- DEFINE_WAKE_Q(wake_q);
-+ LIST_HEAD(to_free);
-
- if (nr_wake < 0 || nr_requeue < 0)
- return -EINVAL;
-@@ -2147,7 +2173,7 @@ static int futex_requeue(u32 __user *uad
- * object.
- */
- this->pi_state = NULL;
-- put_pi_state(pi_state);
-+ put_pi_state_atomic(pi_state, &to_free);
- /*
- * We stop queueing more waiters and let user
- * space deal with the mess.
-@@ -2164,7 +2190,7 @@ static int futex_requeue(u32 __user *uad
- * in futex_proxy_trylock_atomic() or in lookup_pi_state(). We
- * need to drop it here again.
- */
-- put_pi_state(pi_state);
-+ put_pi_state_atomic(pi_state, &to_free);
-
- out_unlock:
- double_unlock_hb(hb1, hb2);
-@@ -2185,6 +2211,7 @@ static int futex_requeue(u32 __user *uad
- out_put_key1:
- put_futex_key(&key1);
- out:
-+ free_pi_state_list(&to_free);
- return ret ? ret : task_count;
- }
-
-@@ -2321,13 +2348,16 @@ static int unqueue_me(struct futex_q *q)
- static void unqueue_me_pi(struct futex_q *q)
- __releases(q->lock_ptr)
- {
-+ struct futex_pi_state *ps;
-+
- __unqueue_futex(q);
-
- BUG_ON(!q->pi_state);
-- put_pi_state(q->pi_state);
-+ ps = __put_pi_state(q->pi_state);
- q->pi_state = NULL;
-
- raw_spin_unlock(q->lock_ptr);
-+ kfree(ps);
- }
-
- static int fixup_pi_state_owner(u32 __user *uaddr, struct futex_q *q,
-@@ -3279,6 +3309,8 @@ static int futex_wait_requeue_pi(u32 __u
- * did a lock-steal - fix up the PI-state in that case.
- */
- if (q.pi_state && (q.pi_state->owner != current)) {
-+ struct futex_pi_state *ps_free;
-+
- raw_spin_lock(q.lock_ptr);
- ret = fixup_pi_state_owner(uaddr2, &q, current);
- if (ret && rt_mutex_owner(&q.pi_state->pi_mutex) == current) {
-@@ -3289,8 +3321,9 @@ static int futex_wait_requeue_pi(u32 __u
- * Drop the reference to the pi state which
- * the requeue_pi() code acquired for us.
- */
-- put_pi_state(q.pi_state);
-+ ps_free = __put_pi_state(q.pi_state);
- raw_spin_unlock(q.lock_ptr);
-+ kfree(ps_free);
- }
- } else {
- struct rt_mutex *pi_mutex;