From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S937099AbdEXOrp (ORCPT ); Wed, 24 May 2017 10:47:45 -0400 Received: from mx0a-001b2d01.pphosted.com ([148.163.156.1]:44438 "EHLO mx0a-001b2d01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933703AbdEXOrh (ORCPT ); Wed, 24 May 2017 10:47:37 -0400 Date: Wed, 24 May 2017 07:47:31 -0700 From: "Paul E. McKenney" To: Masami Hiramatsu Cc: Ingo Molnar , Steven Rostedt , linux-kernel@vger.kernel.org, Peter Zijlstra , Ananth N Mavinakayanahalli , Thomas Gleixner , "H . Peter Anvin" Subject: Re: [RFC PATCH tip/master] kprobes: Use synchronize_rcu_tasks() for optprobe wit CONFIG_PREEMPT Reply-To: paulmck@linux.vnet.ibm.com References: <149562719270.15375.4565081030740506940.stgit@devbox> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <149562719270.15375.4565081030740506940.stgit@devbox> User-Agent: Mutt/1.5.21 (2010-09-15) X-TM-AS-GCONF: 00 x-cbid: 17052414-0056-0000-0000-0000036F5354 X-IBM-SpamModules-Scores: X-IBM-SpamModules-Versions: BY=3.00007111; HX=3.00000241; KW=3.00000007; PH=3.00000004; SC=3.00000212; SDB=6.00864996; UDB=6.00429459; IPR=6.00644776; BA=6.00005372; NDR=6.00000001; ZLA=6.00000005; ZF=6.00000009; ZB=6.00000000; ZP=6.00000000; ZH=6.00000000; ZU=6.00000002; MB=3.00015565; XFM=3.00000015; UTC=2017-05-24 14:47:33 X-IBM-AV-DETECTION: SAVI=unused REMOTE=unused XFE=unused x-cbparentid: 17052414-0057-0000-0000-000007A58725 Message-Id: <20170524144731.GA3956@linux.vnet.ibm.com> X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:,, definitions=2017-05-24_10:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 spamscore=0 suspectscore=0 malwarescore=0 phishscore=0 adultscore=0 bulkscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1703280000 definitions=main-1705240071 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Wed, May 24, 2017 at 09:00:03PM +0900, Masami Hiramatsu wrote: > To enable jump optimized probe with CONFIG_PREEMPT, use > synchronize_rcu_tasks() to wait for all tasks preempted > on trampoline code back on track. > > Since the jump optimized kprobes can replace multiple > instructions, there can be tasks which are preempted > on the 2nd (or 3rd) instructions. If the kprobe > replaces those instructions by a jump instruction, > when those tasks back to the preempted place, it is > a middle of the jump instruction and causes a kernel > panic. > To avoid such tragedies in advance, kprobe optimizer > prepare a detour route using normal kprobe (e.g. > int3 breakpoint on x86), and wait for the tasks which > is interrrupted on such place by synchronize_sched() > when CONFIG_PREEMPT=n. > If CONFIG_PREEMPT=y, things be more complicated, because > such interrupted thread can be preempted (other thread > can be scheduled in interrupt handler.) So, kprobes > optimizer has to wait for those tasks scheduled normally. > In this case we can use synchronize_rcu_tasks() which > ensures that all preempted tasks back on track and > schedule it. > > Signed-off-by: Masami Hiramatsu Acked-by: Paul E. McKenney > --- > arch/Kconfig | 2 +- > kernel/kprobes.c | 23 ++++++++++++++++++++++- > 2 files changed, 23 insertions(+), 2 deletions(-) > > diff --git a/arch/Kconfig b/arch/Kconfig > index 6c00e5b..2abb8de 100644 > --- a/arch/Kconfig > +++ b/arch/Kconfig > @@ -90,7 +90,7 @@ config STATIC_KEYS_SELFTEST > config OPTPROBES > def_bool y > depends on KPROBES && HAVE_OPTPROBES > - depends on !PREEMPT > + select TASKS_RCU if PREEMPT > > config KPROBES_ON_FTRACE > def_bool y > diff --git a/kernel/kprobes.c b/kernel/kprobes.c > index 9f60567..6d69074 100644 > --- a/kernel/kprobes.c > +++ b/kernel/kprobes.c > @@ -377,6 +377,23 @@ static inline void copy_kprobe(struct kprobe *ap, struct kprobe *p) > static bool kprobes_allow_optimization; > > /* > + * Synchronizing wait on trampline code for interrupted tasks/threads. > + * Since the threads running on dynamically allocated trampline code > + * can be interrupted, kprobes has to wait for those tasks back on > + * track and scheduled. If the kernel is preemptive, the thread can be > + * preempted by other tasks on the trampoline too. For such case, this > + * calls synchronize_rcu_tasks() to wait for those tasks back on track. > + */ > +static void synchronize_on_trampoline(void) > +{ > +#ifdef CONFIG_PREEMPT > + synchronize_rcu_tasks(); > +#else > + synchronize_sched(); > +#endif > +} > + > +/* > * Call all pre_handler on the list, but ignores its return value. > * This must be called from arch-dep optimized caller. > */ > @@ -578,8 +595,12 @@ static void kprobe_optimizer(struct work_struct *work) > * there is a chance that Nth instruction is interrupted. In that > * case, running interrupt can return to 2nd-Nth byte of jump > * instruction. This wait is for avoiding it. > + * With CONFIG_PREEMPT, the interrupts can leads preemption. To wait > + * for such thread, we will use synchronize_rcu_tasks() which ensures > + * all preeempted tasks are scheduled normally. So we can ensure there > + * is no threads running there. > */ > - synchronize_sched(); > + synchronize_on_trampoline(); > > /* Step 3: Optimize kprobes after quiesence period */ > do_optimize_kprobes(); >