diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index a2bd8434049..ee90a762b4c 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,17 @@
+2015-09-18  Markus Metzger  <markus.t.metzger@intel.com>
+
+	* NEWS: Announce new scheduler-locking mode.
+	* infrun.c (schedlock_replay): New.
+	(scheduler_enums): Add schedlock_replay.
+	(scheduler_mode): Change default to schedlock_replay.
+	(user_visible_resume_ptid): Handle schedlock_replay.
+	(clear_proceed_status_thread): Stop replaying if resumed thread is
+	not replaying.
+	(schedlock_applies): Handle schedlock_replay.
+	(_initialize_infrun): Document new scheduler-locking mode.
+	* record-btrace.c (record_btrace_resume): Remove code to stop other
+	threads when not replaying the resumed thread.
+
 2015-09-18  Markus Metzger  <markus.t.metzger@intel.com>
 
 	* record-btrace.c ((record_btrace_will_replay): New.
diff --git a/gdb/NEWS b/gdb/NEWS
index 0d17ef4ff1d..86c6f021a18 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -45,6 +45,9 @@ show remote multiprocess-extensions-packet
   The "/m" option is now considered deprecated: its "source-centric"
   output hasn't proved useful in practice.
 
+* The "set scheduler-locking" command supports a new mode "replay".
+  It behaves like "off" in record mode and like "on" in replay mode.
+
 * Support for various ROM monitors has been removed:
 
   target dbug		dBUG ROM monitor for Motorola ColdFire
diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog
index 1e16e929322..9164b89379e 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,3 +1,7 @@
+2015-09-18  Markus Metzger  <markus.t.metzger@intel.com>
+
+	* gdb.texinfo (All-Stop Mode): Describe new scheduler-locking mode.
+
 2015-09-15  Pedro Alves  <palves@redhat.com>
 
 	PR remote/18965
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index 4ecdb8fc7b7..06870396301 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -5836,17 +5836,20 @@ locking the OS scheduler to allow only a single thread to run.
 @item set scheduler-locking @var{mode}
 @cindex scheduler locking mode
 @cindex lock scheduler
-Set the scheduler locking mode.  If it is @code{off}, then there is no
-locking and any thread may run at any time.  If @code{on}, then only the
-current thread may run when the inferior is resumed.  The @code{step}
-mode optimizes for single-stepping; it prevents other threads 
-from preempting the current thread while you are stepping, so that 
-the focus of debugging does not change unexpectedly.
-Other threads never get a chance to run when you step, and they are
-completely free to run when you use commands
-like @samp{continue}, @samp{until}, or @samp{finish}.  However, unless another
-thread hits a breakpoint during its timeslice, @value{GDBN} does not change
-the current thread away from the thread that you are debugging.
+Set the scheduler locking mode.  It applies to normal execution,
+record mode, and replay mode.  If it is @code{off}, then there is no
+locking and any thread may run at any time.  If @code{on}, then only
+the current thread may run when the inferior is resumed.  The
+@code{step} mode optimizes for single-stepping; it prevents other
+threads from preempting the current thread while you are stepping, so
+that the focus of debugging does not change unexpectedly.  Other
+threads never get a chance to run when you step, and they are
+completely free to run when you use commands like @samp{continue},
+@samp{until}, or @samp{finish}.  However, unless another thread hits a
+breakpoint during its timeslice, @value{GDBN} does not change the
+current thread away from the thread that you are debugging.  The
+@code{replay} mode behaves like @code{off} in record mode and like
+@code{on} in replay mode.
 
 @item show scheduler-locking
 Display the current scheduler locking mode.
diff --git a/gdb/infrun.c b/gdb/infrun.c
index 75ac80abd9f..701ea37eb5d 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -2166,13 +2166,15 @@ resume_cleanups (void *ignore)
 static const char schedlock_off[] = "off";
 static const char schedlock_on[] = "on";
 static const char schedlock_step[] = "step";
+static const char schedlock_replay[] = "replay";
 static const char *const scheduler_enums[] = {
   schedlock_off,
   schedlock_on,
   schedlock_step,
+  schedlock_replay,
   NULL
 };
-static const char *scheduler_mode = schedlock_off;
+static const char *scheduler_mode = schedlock_replay;
 static void
 show_scheduler_mode (struct ui_file *file, int from_tty,
 		     struct cmd_list_element *c, const char *value)
@@ -2238,6 +2240,13 @@ user_visible_resume_ptid (int step)
 	 resume.  */
       resume_ptid = inferior_ptid;
     }
+  else if ((scheduler_mode == schedlock_replay)
+	   && target_record_will_replay (minus_one_ptid, execution_direction))
+    {
+      /* User-settable 'scheduler' mode requires solo thread resume in replay
+	 mode.  */
+      resume_ptid = inferior_ptid;
+    }
   else if (!sched_multi && target_supports_multi_process ())
     {
       /* Resume all threads of the current process (and none of other
@@ -2803,6 +2812,18 @@ clear_proceed_status_thread (struct thread_info *tp)
 void
 clear_proceed_status (int step)
 {
+  /* With scheduler-locking replay, stop replaying other threads if we're
+     not replaying the user-visible resume ptid.
+
+     This is a convenience feature to not require the user to explicitly
+     stop replaying the other threads.  We're assuming that the user's
+     intent is to resume tracing the recorded process.  */
+  if (!non_stop && scheduler_mode == schedlock_replay
+      && target_record_is_replaying (minus_one_ptid)
+      && !target_record_will_replay (user_visible_resume_ptid (step),
+				     execution_direction))
+    target_record_stop_replaying ();
+
   if (!non_stop)
     {
       struct thread_info *tp;
@@ -2890,7 +2911,10 @@ schedlock_applies (struct thread_info *tp)
 {
   return (scheduler_mode == schedlock_on
 	  || (scheduler_mode == schedlock_step
-	      && tp->control.stepping_command));
+	      && tp->control.stepping_command)
+	  || (scheduler_mode == schedlock_replay
+	      && target_record_will_replay (minus_one_ptid,
+					    execution_direction)));
 }
 
 /* Basic routine for continuing the program in various fashions.
@@ -9187,10 +9211,13 @@ By default, the debugger will use the same inferior."),
 			scheduler_enums, &scheduler_mode, _("\
 Set mode for locking scheduler during execution."), _("\
 Show mode for locking scheduler during execution."), _("\
-off  == no locking (threads may preempt at any time)\n\
-on   == full locking (no thread except the current thread may run)\n\
-step == scheduler locked during stepping commands (step, next, stepi, nexti).\n\
-	In this mode, other threads may run during other commands."),
+off    == no locking (threads may preempt at any time)\n\
+on     == full locking (no thread except the current thread may run)\n\
+          This applies to both normal execution and replay mode.\n\
+step   == scheduler locked during stepping commands (step, next, stepi, nexti).\n\
+          In this mode, other threads may run during other commands.\n\
+          This applies to both normal execution and replay mode.\n\
+replay == scheduler locked in replay mode and unlocked during normal execution."),
 			set_schedlock_func,	/* traps on target vector */
 			show_scheduler_mode,
 			&setlist, &showlist);
diff --git a/gdb/record-btrace.c b/gdb/record-btrace.c
index df15d7770fc..42195d1a1ec 100644
--- a/gdb/record-btrace.c
+++ b/gdb/record-btrace.c
@@ -1903,22 +1903,16 @@ record_btrace_resume (struct target_ops *ops, ptid_t ptid, int step,
      to not change the execution direction in-between.  */
   record_btrace_resume_exec_dir = execution_direction;
 
-  /* For all-stop targets...  */
+  /* For all-stop targets we pick the current thread when asked to resume an
+     entire process or everything.  */
   if (!target_is_non_stop_p ())
     {
-      /* ...we pick the current thread when asked to resume an entire process
-	 or everything.  */
       if (ptid_equal (minus_one_ptid, ptid) || ptid_is_pid (ptid))
 	ptid = inferior_ptid;
 
       tp = find_thread_ptid (ptid);
       if (tp == NULL)
 	error (_("Cannot find thread to resume."));
-
-      /* ...and we stop replaying other threads if the thread to resume is not
-	 replaying.  */
-      if (!btrace_is_replaying (tp) && execution_direction != EXEC_REVERSE)
-	target_record_stop_replaying ();
     }
 
   /* As long as we're not replaying, just forward the request.