From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752801AbcLFWug (ORCPT ); Tue, 6 Dec 2016 17:50:36 -0500 Received: from smtprelay0209.hostedemail.com ([216.40.44.209]:48313 "EHLO smtprelay.hostedemail.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1751839AbcLFWue (ORCPT ); Tue, 6 Dec 2016 17:50:34 -0500 X-Session-Marker: 726F737465647440676F6F646D69732E6F7267 X-Spam-Summary: 2,0,0,,d41d8cd98f00b204,rostedt@goodmis.org,:::::::::::::,RULES_HIT:41:355:379:541:800:960:973:988:989:1260:1277:1311:1313:1314:1345:1437:1515:1516:1518:1534:1542:1593:1594:1711:1730:1747:1777:1792:2194:2199:2393:2559:2562:2693:2897:2904:3138:3139:3140:3141:3142:3353:3865:3867:3868:3870:3871:3874:4321:4605:5007:6261:7875:7903:8660:10004:10400:10848:11026:11473:11658:11914:12043:12114:12291:12296:12438:12555:12679:12683:12740:12760:12986:13148:13161:13229:13230:13439:14037:14096:14097:14181:14394:14659:14721:21080:21451:30054,0,RBL:none,CacheIP:none,Bayesian:0.5,0.5,0.5,Netcheck:none,DomainCache:0,MSF:not bulk,SPF:fn,MSBL:0,DNSBL:none,Custom_rules:0:0:0,LFtime:2,LUA_SUMMARY:none X-HE-Tag: toy73_5c05edcfa7a4f X-Filterd-Recvd-Size: 3687 Date: Tue, 6 Dec 2016 17:50:30 -0500 From: Steven Rostedt To: LKML , linux-rt-users Cc: Thomas Gleixner , Sebastian Andrzej Siewior , Clark Williams , "Luis Claudio R. Goncalves" , John Kacur Subject: [PATCH RT] net: Have __napi_schedule_irqoff() disable interrupts on RT Message-ID: <20161206175030.636989f0@gandalf.local.home> X-Mailer: Claws Mail 3.14.0 (GTK+ 2.24.31; x86_64-pc-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org A customer hit a crash where the napi sd->poll_list became corrupted. The customer had the bnx2x driver, which does a __napi_schedule_irqoff() in its interrupt handler. Unfortunately, when running with CONFIG_PREEMPT_RT_FULL, this interrupt handler is run as a thread and is preemptable. The call to ____napi_schedule() must be done with interrupts disabled to protect the per cpu softnet_data's poll_list, which is protected by disabling interrupts (disabling preemption is enough when all interrupts are threaded and local_bh_disable() can't preempt). As bnx2x isn't the only driver that does this, the safest thing to do is to make __napi_schedule_irqoff() call __napi_schedule() instead when CONFIG_PREEMPT_RT_FULL is enabled, which will call local_irq_save() before calling ____napi_schedule(). Cc: stable-rt@vger.kernel.org Signed-off-by: Steven Rostedt (Red Hat) --- include/linux/netdevice.h | 12 ++++++++++++ net/core/dev.c | 2 ++ 2 files changed, 14 insertions(+) Index: linux-rt.git/include/linux/netdevice.h =================================================================== --- linux-rt.git.orig/include/linux/netdevice.h 2016-11-18 14:59:01.679547362 -0500 +++ linux-rt.git/include/linux/netdevice.h 2016-12-06 17:35:38.506672042 -0500 @@ -395,7 +395,19 @@ typedef enum rx_handler_result rx_handle typedef rx_handler_result_t rx_handler_func_t(struct sk_buff **pskb); void __napi_schedule(struct napi_struct *n); + +/* + * When PREEMPT_RT_FULL is defined, all device interrupt handlers + * run as threads, and they can also be preempted (without PREEMPT_RT + * interrupt threads can not be preempted). Which means that calling + * __napi_schedule_irqoff() from an interrupt handler can be preempted + * and can corrupt the napi->poll_list. + */ +#ifdef CONFIG_PREEMPT_RT_FULL +#define __napi_schedule_irqoff(n) __napi_schedule(n) +#else void __napi_schedule_irqoff(struct napi_struct *n); +#endif static inline bool napi_disable_pending(struct napi_struct *n) { Index: linux-rt.git/net/core/dev.c =================================================================== --- linux-rt.git.orig/net/core/dev.c 2016-11-18 14:59:02.876527251 -0500 +++ linux-rt.git/net/core/dev.c 2016-12-06 17:35:38.513672035 -0500 @@ -4910,6 +4910,7 @@ void __napi_schedule(struct napi_struct } EXPORT_SYMBOL(__napi_schedule); +#ifndef CONFIG_PREEMPT_RT_FULL /** * __napi_schedule_irqoff - schedule for receive * @n: entry to schedule @@ -4921,6 +4922,7 @@ void __napi_schedule_irqoff(struct napi_ ____napi_schedule(this_cpu_ptr(&softnet_data), n); } EXPORT_SYMBOL(__napi_schedule_irqoff); +#endif void __napi_complete(struct napi_struct *n) {