All of lore.kernel.org
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	"Peter Zijlstra (Intel)" <peterz@infradead.org>,
	juri.lelli@arm.com, bigeasy@linutronix.de, xlpang@redhat.com,
	rostedt@goodmis.org, mathieu.desnoyers@efficios.com,
	jdesfossez@efficios.com, dvhart@infradead.org,
	bristot@redhat.com, Thomas Gleixner <tglx@linutronix.de>,
	Lee Jones <lee.jones@linaro.org>
Subject: [PATCH 4.4 04/38] futex: Rework inconsistent rt_mutex/futex_q state
Date: Mon,  8 Feb 2021 16:00:26 +0100	[thread overview]
Message-ID: <20210208145805.463603952@linuxfoundation.org> (raw)
In-Reply-To: <20210208145805.279815326@linuxfoundation.org>

From: Lee Jones <lee.jones@linaro.org>

From: Peter Zijlstra <peterz@infradead.org>

[Upstream commit 73d786bd043ebc855f349c81ea805f6b11cbf2aa ]

There is a weird state in the futex_unlock_pi() path when it interleaves
with a concurrent futex_lock_pi() at the point where it drops hb->lock.

In this case, it can happen that the rt_mutex wait_list and the futex_q
disagree on pending waiters, in particular rt_mutex will find no pending
waiters where futex_q thinks there are. In this case the rt_mutex unlock
code cannot assign an owner.

The futex side fixup code has to cleanup the inconsistencies with quite a
bunch of interesting corner cases.

Simplify all this by changing wake_futex_pi() to return -EAGAIN when this
situation occurs. This then gives the futex_lock_pi() code the opportunity
to continue and the retried futex_unlock_pi() will now observe a coherent
state.

The only problem is that this breaks RT timeliness guarantees. That
is, consider the following scenario:

  T1 and T2 are both pinned to CPU0. prio(T2) > prio(T1)

    CPU0

    T1
      lock_pi()
      queue_me()  <- Waiter is visible

    preemption

    T2
      unlock_pi()
	loops with -EAGAIN forever

Which is undesirable for PI primitives. Future patches will rectify
this.

Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: juri.lelli@arm.com
Cc: bigeasy@linutronix.de
Cc: xlpang@redhat.com
Cc: rostedt@goodmis.org
Cc: mathieu.desnoyers@efficios.com
Cc: jdesfossez@efficios.com
Cc: dvhart@infradead.org
Cc: bristot@redhat.com
Link: http://lkml.kernel.org/r/20170322104151.850383690@infradead.org
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
[Lee: Back-ported to solve a dependency]
Signed-off-by: Lee Jones <lee.jones@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
 kernel/futex.c |   52 +++++++++++++++-------------------------------------
 1 file changed, 15 insertions(+), 37 deletions(-)

--- a/kernel/futex.c
+++ b/kernel/futex.c
@@ -1389,12 +1389,19 @@ static int wake_futex_pi(u32 __user *uad
 	new_owner = rt_mutex_next_owner(&pi_state->pi_mutex);
 
 	/*
-	 * It is possible that the next waiter (the one that brought
-	 * this owner to the kernel) timed out and is no longer
-	 * waiting on the lock.
-	 */
-	if (!new_owner)
-		new_owner = this->task;
+	 * When we interleave with futex_lock_pi() where it does
+	 * rt_mutex_timed_futex_lock(), we might observe @this futex_q waiter,
+	 * but the rt_mutex's wait_list can be empty (either still, or again,
+	 * depending on which side we land).
+	 *
+	 * When this happens, give up our locks and try again, giving the
+	 * futex_lock_pi() instance time to complete, either by waiting on the
+	 * rtmutex or removing itself from the futex queue.
+	 */
+	if (!new_owner) {
+		raw_spin_unlock_irq(&pi_state->pi_mutex.wait_lock);
+		return -EAGAIN;
+	}
 
 	/*
 	 * We pass it to the next owner. The WAITERS bit is always
@@ -2337,7 +2344,6 @@ static long futex_wait_restart(struct re
  */
 static int fixup_owner(u32 __user *uaddr, struct futex_q *q, int locked)
 {
-	struct task_struct *owner;
 	int ret = 0;
 
 	if (locked) {
@@ -2351,43 +2357,15 @@ static int fixup_owner(u32 __user *uaddr
 	}
 
 	/*
-	 * Catch the rare case, where the lock was released when we were on the
-	 * way back before we locked the hash bucket.
-	 */
-	if (q->pi_state->owner == current) {
-		/*
-		 * Try to get the rt_mutex now. This might fail as some other
-		 * task acquired the rt_mutex after we removed ourself from the
-		 * rt_mutex waiters list.
-		 */
-		if (rt_mutex_futex_trylock(&q->pi_state->pi_mutex)) {
-			locked = 1;
-			goto out;
-		}
-
-		/*
-		 * pi_state is incorrect, some other task did a lock steal and
-		 * we returned due to timeout or signal without taking the
-		 * rt_mutex. Too late.
-		 */
-		raw_spin_lock(&q->pi_state->pi_mutex.wait_lock);
-		owner = rt_mutex_owner(&q->pi_state->pi_mutex);
-		if (!owner)
-			owner = rt_mutex_next_owner(&q->pi_state->pi_mutex);
-		raw_spin_unlock(&q->pi_state->pi_mutex.wait_lock);
-		ret = fixup_pi_state_owner(uaddr, q, owner);
-		goto out;
-	}
-
-	/*
 	 * Paranoia check. If we did not take the lock, then we should not be
 	 * the owner of the rt_mutex.
 	 */
-	if (rt_mutex_owner(&q->pi_state->pi_mutex) == current)
+	if (rt_mutex_owner(&q->pi_state->pi_mutex) == current) {
 		printk(KERN_ERR "fixup_owner: ret = %d pi-mutex: %p "
 				"pi-state %p\n", ret,
 				q->pi_state->pi_mutex.owner,
 				q->pi_state->owner);
+	}
 
 out:
 	return ret ? ret : locked;



  parent reply	other threads:[~2021-02-08 15:09 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-02-08 15:00 [PATCH 4.4 00/38] 4.4.257-rc1 review Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.4 01/38] net_sched: reject silly cell_log in qdisc_get_rtab() Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.4 02/38] futex,rt_mutex: Provide futex specific rt_mutex API Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.4 03/38] futex: Remove rt_mutex_deadlock_account_*() Greg Kroah-Hartman
2021-02-08 15:00 ` Greg Kroah-Hartman [this message]
2021-02-08 15:00 ` [PATCH 4.4 05/38] futex: Avoid violating the 10th rule of futex Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.4 06/38] futex: Replace pointless printk in fixup_owner() Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.4 07/38] futex: Provide and use pi_state_update_owner() Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.4 08/38] rtmutex: Remove unused argument from rt_mutex_proxy_unlock() Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.4 09/38] futex: Use pi_state_update_owner() in put_pi_state() Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.4 10/38] futex: Simplify fixup_pi_state_owner() Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.4 11/38] futex: Handle faults correctly for PI futexes Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.4 12/38] usb: udc: core: Use lock when write to soft_connect Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.4 13/38] scsi: libfc: Avoid invoking response handler twice if ep is already completed Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.4 14/38] scsi: ibmvfc: Set default timeout to avoid crash during migration Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.4 15/38] stable: clamp SUBLEVEL in 4.4 and 4.9 Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.4 16/38] USB: serial: cp210x: add pid/vid for WSDA-200-USB Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.4 17/38] USB: serial: cp210x: add new VID/PID for supporting Teraoka AD2000 Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.4 18/38] USB: serial: option: Adding support for Cinterion MV31 Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.4 19/38] Input: i8042 - unbreak Pegatron C15B Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.4 20/38] net: lapb: Copy the skb before sending a packet Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.4 21/38] ELF/MIPS build fix Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.4 22/38] elfcore: fix building with clang Greg Kroah-Hartman
2021-02-09 12:52   ` Pavel Machek
2021-02-09 13:01     ` Greg Kroah-Hartman
2021-02-09 19:10       ` Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.4 23/38] USB: gadget: legacy: fix an error code in eth_bind() Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.4 24/38] USB: usblp: dont call usb_set_interface if theres a single alt Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.4 25/38] usb: dwc2: Fix endpoint direction check in ep_from_windex Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.4 26/38] mac80211: fix station rate table updates on assoc Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.4 27/38] kretprobe: Avoid re-registration of the same kretprobe earlier Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.4 28/38] cifs: report error instead of invalid when revalidating a dentry fails Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.4 29/38] mmc: core: Limit retries when analyse of SDIO tuples fails Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.4 30/38] ARM: footbridge: fix dc21285 PCI configuration accessors Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.4 31/38] mm: hugetlbfs: fix cannot migrate the fallocated HugeTLB page Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.4 32/38] mm: hugetlb: fix a race between isolating and freeing page Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.4 33/38] mm: hugetlb: remove VM_BUG_ON_PAGE from page_huge_active Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.4 34/38] x86/build: Disable CET instrumentation in the kernel Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.4 35/38] x86/apic: Add extra serialization for non-serializing MSRs Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.4 36/38] Input: xpad - sync supported devices with fork on GitHub Greg Kroah-Hartman
2021-02-08 15:00 ` [PATCH 4.4 37/38] ACPI: thermal: Do not call acpi_thermal_check() directly Greg Kroah-Hartman
2021-02-08 15:01 ` [PATCH 4.4 38/38] ALSA: hda/realtek - Fix typo of pincfg for Dell quirk Greg Kroah-Hartman
2021-02-08 18:36 ` [PATCH 4.4 00/38] 4.4.257-rc1 review Pavel Machek
2021-02-08 20:43 ` Shuah Khan
2021-02-09 18:09 ` Guenter Roeck
2021-02-10  5:04 ` Naresh Kamboju

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210208145805.463603952@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=bigeasy@linutronix.de \
    --cc=bristot@redhat.com \
    --cc=dvhart@infradead.org \
    --cc=jdesfossez@efficios.com \
    --cc=juri.lelli@arm.com \
    --cc=lee.jones@linaro.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mathieu.desnoyers@efficios.com \
    --cc=peterz@infradead.org \
    --cc=rostedt@goodmis.org \
    --cc=stable@vger.kernel.org \
    --cc=tglx@linutronix.de \
    --cc=xlpang@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.