mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Waiman Long <llong@redhat.com>
To: Peter Zijlstra <peterz@infradead.org>, Waiman Long <llong@redhat.com>
Cc: Ingo Molnar <mingo@redhat.com>, Will Deacon <will@kernel.org>,
	Boqun Feng <boqun.feng@gmail.com>,
	linux-kernel@vger.kernel.org,
	Thomas Gleixner <tglx@linutronix.de>,
	Luis Goncalves <lgoncalv@redhat.com>,
	Chunyu Hu <chuhu@redhat.com>
Subject: Re: [PATCH] locking/rtmutex: Always use trylock in rt_mutex_trylock()
Date: Tue, 8 Oct 2024 09:21:34 -0400	[thread overview]
Message-ID: <ce60b576-b8bd-49da-90b1-a84c7cb0eb9e@redhat.com> (raw)
In-Reply-To: <20241008073800.GD14587@noisy.programming.kicks-ass.net>

On 10/8/24 3:38 AM, Peter Zijlstra wrote:
> On Mon, Oct 07, 2024 at 11:54:54AM -0400, Waiman Long wrote:
>> On 10/7/24 11:33 AM, Peter Zijlstra wrote:
>>> On Mon, Oct 07, 2024 at 11:23:32AM -0400, Waiman Long wrote:
>>>
>>>>> Is the problem that:
>>>>>
>>>>> 	sched_tick()
>>>             raw_spin_lock(&rq->__lock);
>>>>> 	  task_tick_mm_cid()
>>>>> 	    task_work_add()
>>>>> 	      kasan_save_stack()
>>>>> 	        idiotic crap while holding rq->__lock ?
>>>>>
>>>>> Because afaict that is completely insane. And has nothing to do with
>>>>> rtmutex.
>>>>>
>>>>> We are not going to change rtmutex because instrumentation shit is shit.
>>>> Yes, it is because of KASAN that causes page allocation while holding the
>>>> rq->__lock. Maybe we can blame KASAN for this. It is actually not a problem
>>>> for non-PREEMPT_RT kernel because only trylock is being used. However, we
>>>> don't use trylock all the way when rt_spin_trylock() is being used with
>>>> PREEMPT_RT Kernel.
>>> It has nothing to do with trylock, an everything to do with scheduler
>>> locks being special.
>>>
>>> But even so, trying to squirrel a spinlock inside a raw_spinlock is
>>> dodgy at the best of times, yes it mostly works, but should be avoided
>>> whenever possible.
>>>
>>> And instrumentation just doesn't count.
>>>
>>>> This is certainly a problem that we need to fix as there
>>>> may be other similar case not involving rq->__lock lurking somewhere.
>>> There cannot be, lock order is:
>>>
>>>     rtmutex->wait_lock
>>>       task->pi_lock
>>>         rq->__lock
>>>
>>> Trying to subvert that order gets you a splat, any other:
>>>
>>>     raw_spin_lock(&foo);
>>>     spin_trylock(&bar);
>>>
>>> will 'work', despite probably not being a very good idea.
>>>
>>> Any case involving the scheduler locks needs to be eradicated, not
>>> worked around.
>> OK, I will see what I can do to work around this issue.
> Something like the completely untested below might just work.

The real problem is due to the occasional need to allocate new pages to 
expand the stack buffer in stack depot that will take additional lock. 
Fortunately, there is a kasan_record_aux_stack_noalloc() variant that 
will prevent that. Below is my proposed solution that is less restrictive.

diff --git a/include/linux/task_work.h b/include/linux/task_work.h
index cf5e7e891a77..2964171856e0 100644
--- a/include/linux/task_work.h
+++ b/include/linux/task_work.h
@@ -14,11 +14,14 @@ init_task_work(struct callback_head *twork, 
task_work_func_t func)
  }

  enum task_work_notify_mode {
-    TWA_NONE,
+    TWA_NONE = 0,
      TWA_RESUME,
      TWA_SIGNAL,
      TWA_SIGNAL_NO_IPI,
      TWA_NMI_CURRENT,
+
+    TWA_FLAGS = 0xff00,
+    TWAF_NO_ALLOC = 0x0100,
  };

  static inline bool task_work_pending(struct task_struct *task)
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 43e453ab7e20..0259301e572e 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -10458,7 +10458,9 @@ void task_tick_mm_cid(struct rq *rq, struct 
task_struct *curr)
          return;
      if (time_before(now, READ_ONCE(curr->mm->mm_cid_next_scan)))
          return;
-    task_work_add(curr, work, TWA_RESUME);
+
+    /* No page allocation under rq lock */
+    task_work_add(curr, work, TWA_RESUME | TWAF_NO_ALLOC);
  }

  void sched_mm_cid_exit_signals(struct task_struct *t)
diff --git a/kernel/task_work.c b/kernel/task_work.c
index 5d14d639ac71..c969f1f26be5 100644
--- a/kernel/task_work.c
+++ b/kernel/task_work.c
@@ -55,15 +55,26 @@ int task_work_add(struct task_struct *task, struct 
callback_head *work,
            enum task_work_notify_mode notify)
  {
      struct callback_head *head;
+    int flags = notify & TWA_FLAGS;

+    notify &= ~TWA_FLAGS;
      if (notify == TWA_NMI_CURRENT) {
          if (WARN_ON_ONCE(task != current))
              return -EINVAL;
          if (!IS_ENABLED(CONFIG_IRQ_WORK))
              return -EINVAL;
      } else {
-        /* record the work call stack in order to print it in KASAN 
reports */
-        kasan_record_aux_stack(work);
+        /*
+         * Record the work call stack in order to print it in KASAN
+         * reports.
+         *
+         * Note that stack allocation can fail if TWAF_NO_ALLOC flag
+         * is set and new page is needed to expand the stack buffer.
+         */
+        if (flags & TWAF_NO_ALLOC)
+            kasan_record_aux_stack_noalloc(work);
+        else
+            kasan_record_aux_stack(work);
      }

      head = READ_ONCE(task->task_works);


      reply	other threads:[~2024-10-08 13:21 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-09-26 15:13 Waiman Long
2024-10-02  9:37 ` Peter Zijlstra
2024-10-02 17:54   ` Waiman Long
2024-10-07 14:50     ` Peter Zijlstra
2024-10-07 15:23       ` Waiman Long
2024-10-07 15:33         ` Peter Zijlstra
2024-10-07 15:54           ` Waiman Long
2024-10-08  7:38             ` Peter Zijlstra
2024-10-08 13:21               ` Waiman Long [this message]

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=ce60b576-b8bd-49da-90b1-a84c7cb0eb9e@redhat.com \
    --to=llong@redhat.com \
    --cc=boqun.feng@gmail.com \
    --cc=chuhu@redhat.com \
    --cc=lgoncalv@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mingo@redhat.com \
    --cc=peterz@infradead.org \
    --cc=tglx@linutronix.de \
    --cc=will@kernel.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®