Patch "rcutorture: Fix stuttering races and other issues" has been added to the 6.6-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    rcutorture: Fix stuttering races and other issues

to the 6.6-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     rcutorture-fix-stuttering-races-and-other-issues.patch
and it can be found in the queue-6.6 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 6b13da968c234929a21e3dc1e7120e617481ad86
Author: Joel Fernandes (Google) <joel@xxxxxxxxxxxxxxxxx>
Date:   Sat Jul 29 14:27:31 2023 +0000

    rcutorture: Fix stuttering races and other issues
    
    [ Upstream commit cca42bd8eb1b54a4c9bbf48c79d120e66619a3e4 ]
    
    The stuttering code isn't functioning as expected. Ideally, it should
    pause the torture threads for a designated period before resuming. Yet,
    it fails to halt the test for the correct duration. Additionally, a race
    condition exists, potentially causing the stuttering code to pause for
    an extended period if the 'spt' variable is non-zero due to the stutter
    orchestration thread's inadequate CPU time.
    
    Moreover, over-stuttering can hinder RCU's progress on TREE07 kernels.
    This happens as the stuttering code may run within a softirq due to RCU
    callbacks. Consequently, ksoftirqd keeps a CPU busy for several seconds,
    thus obstructing RCU's progress. This situation triggers a warning
    message in the logs:
    
    [ 2169.481783] rcu_torture_writer: rtort_pipe_count: 9
    
    This warning suggests that an RCU torture object, although invisible to
    RCU readers, couldn't make it past the pipe array and be freed -- a
    strong indication that there weren't enough grace periods during the
    stutter interval.
    
    To address these issues, this patch sets the "stutter end" time to an
    absolute point in the future set by the main stutter thread. This is
    then used for waiting in stutter_wait(). While the stutter thread still
    defines this absolute time, the waiters' waiting logic doesn't rely on
    the stutter thread receiving sufficient CPU time to halt the stuttering
    as the halting is now self-controlled.
    
    Cc: stable@xxxxxxxxxxxxxxx
    Signed-off-by: Joel Fernandes (Google) <joel@xxxxxxxxxxxxxxxxx>
    Signed-off-by: Paul E. McKenney <paulmck@xxxxxxxxxx>
    Signed-off-by: Frederic Weisbecker <frederic@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/kernel/torture.c b/kernel/torture.c
index e851b8e9390b3..c7b475883b9a8 100644
--- a/kernel/torture.c
+++ b/kernel/torture.c
@@ -721,7 +721,7 @@ static void torture_shutdown_cleanup(void)
  * suddenly applied to or removed from the system.
  */
 static struct task_struct *stutter_task;
-static int stutter_pause_test;
+static ktime_t stutter_till_abs_time;
 static int stutter;
 static int stutter_gap;
 
@@ -731,30 +731,16 @@ static int stutter_gap;
  */
 bool stutter_wait(const char *title)
 {
-	unsigned int i = 0;
 	bool ret = false;
-	int spt;
+	ktime_t till_ns;
 
 	cond_resched_tasks_rcu_qs();
-	spt = READ_ONCE(stutter_pause_test);
-	for (; spt; spt = READ_ONCE(stutter_pause_test)) {
-		if (!ret && !rt_task(current)) {
-			sched_set_normal(current, MAX_NICE);
-			ret = true;
-		}
-		if (spt == 1) {
-			torture_hrtimeout_jiffies(1, NULL);
-		} else if (spt == 2) {
-			while (READ_ONCE(stutter_pause_test)) {
-				if (!(i++ & 0xffff))
-					torture_hrtimeout_us(10, 0, NULL);
-				cond_resched();
-			}
-		} else {
-			torture_hrtimeout_jiffies(round_jiffies_relative(HZ), NULL);
-		}
-		torture_shutdown_absorb(title);
+	till_ns = READ_ONCE(stutter_till_abs_time);
+	if (till_ns && ktime_before(ktime_get(), till_ns)) {
+		torture_hrtimeout_ns(till_ns, 0, HRTIMER_MODE_ABS, NULL);
+		ret = true;
 	}
+	torture_shutdown_absorb(title);
 	return ret;
 }
 EXPORT_SYMBOL_GPL(stutter_wait);
@@ -765,23 +751,16 @@ EXPORT_SYMBOL_GPL(stutter_wait);
  */
 static int torture_stutter(void *arg)
 {
-	DEFINE_TORTURE_RANDOM(rand);
-	int wtime;
+	ktime_t till_ns;
 
 	VERBOSE_TOROUT_STRING("torture_stutter task started");
 	do {
 		if (!torture_must_stop() && stutter > 1) {
-			wtime = stutter;
-			if (stutter > 2) {
-				WRITE_ONCE(stutter_pause_test, 1);
-				wtime = stutter - 3;
-				torture_hrtimeout_jiffies(wtime, &rand);
-				wtime = 2;
-			}
-			WRITE_ONCE(stutter_pause_test, 2);
-			torture_hrtimeout_jiffies(wtime, NULL);
+			till_ns = ktime_add_ns(ktime_get(),
+					       jiffies_to_nsecs(stutter));
+			WRITE_ONCE(stutter_till_abs_time, till_ns);
+			torture_hrtimeout_jiffies(stutter - 1, NULL);
 		}
-		WRITE_ONCE(stutter_pause_test, 0);
 		if (!torture_must_stop())
 			torture_hrtimeout_jiffies(stutter_gap, NULL);
 		torture_shutdown_absorb("torture_stutter");



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux