Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1755980AbcCBULl (ORCPT ); Wed, 2 Mar 2016 15:11:41 -0500 Received: from mail-db3on0093.outbound.protection.outlook.com ([157.55.234.93]:36256 "EHLO emea01-db3-obe.outbound.protection.outlook.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1755321AbcCBUKb (ORCPT ); Wed, 2 Mar 2016 15:10:31 -0500 Authentication-Results: spf=fail (sender IP is 12.216.194.146) smtp.mailfrom=ezchip.com; ezchip.com; dkim=none (message not signed) header.d=none;ezchip.com; dmarc=none action=none header.from=ezchip.com; From: Chris Metcalf To: Gilad Ben Yossef , Steven Rostedt , Ingo Molnar , Peter Zijlstra , Andrew Morton , "Rik van Riel" , Tejun Heo , Frederic Weisbecker , Thomas Gleixner , "Paul E. McKenney" , Christoph Lameter , Viresh Kumar , Catalin Marinas , Will Deacon , Andy Lutomirski , , CC: Chris Metcalf Subject: [PATCH v10 07/12] task_isolation: add debug boot flag Date: Wed, 2 Mar 2016 15:09:31 -0500 Message-ID: <1456949376-4910-8-git-send-email-cmetcalf@ezchip.com> X-Mailer: git-send-email 2.1.2 In-Reply-To: <1456949376-4910-1-git-send-email-cmetcalf@ezchip.com> References: <1456949376-4910-1-git-send-email-cmetcalf@ezchip.com> X-EOPAttributedMessage: 0 X-Forefront-Antispam-Report: CPI:12.216.194.146;IPV:NLI;CTRY:US;EFV:NLI;SFV:NSPM;SFS:(10009020)(979002)(6009001)(2980300002)(1109001)(339900001)(189002)(199003)(48376002)(5001770100001)(5001970100001)(1220700001)(1096002)(4326007)(6806005)(85426001)(107886002)(33646002)(104016004)(19580405001)(5008740100001)(2950100001)(586003)(2906002)(19580395003)(50466002)(4001430100002)(87936001)(575784001)(81156012)(2201001)(50986999)(105606002)(47776003)(76176999)(106466001)(36756003)(5003940100001)(229853001)(92566002)(42186005)(11100500001)(189998001)(50226001)(81166004)(921003)(42882005)(1121003)(83996005)(2101003)(969003)(989001)(999001)(1009001)(1019001);DIR:OUT;SFP:1101;SCL:1;SRVR:VI1PR05MB1694;H:ld-1.internal.tilera.com;FPR:;SPF:None;MLV:ovrnspm;MX:1;A:1;PTR:wb-fw1.tilera.com;LANG:en; X-Microsoft-Exchange-Diagnostics: 1;DB3FFO11FD051;1:t7aliFY24wsPCPfBkvCXfCZKe+3zIJLNSaX8Hf6VRBgeQiUAQ6MASbGfEmjpbX5eOVytwu/zEp4xpD0U9hTnBhEmP5ExUvo8jGBq+8nleziswEij4YHiQhuhOE6L/lR0u4bJ+dC/ljg8y2L7Ir/eSFrgDHT9nZPNgLxq4UiqdxgkzkYSdHqJ9gTdlDjf8YzGGRviIUvBrIiqszcLT90POhfeNCUcMEUwAODn+Be2BLfqRGI7hk871LY/KfhYyn6qCRmA0liJpx7wKrfChqWxIU+DASuvZrfnX1H9JpQalnOyQls23x5ztRv6RYuKFgLsmsHH2Y2jjCQcaxFVjD4DTDLo/jw6RY/2YI52PRHtTvizSN02pH5J53mKOnrc72VdYExv7snA7CHpbPaSotYcIYO+TkUl+24q/0pwSEowkEWr6cbY42ThjJdqwI8iQk8WbBHxPQf2o0bYwce0yxeDMyDPqjiWokSteDWyACICTK2K5kTBhH2qMT4QtHXvotJe MIME-Version: 1.0 Content-Type: text/plain X-MS-Office365-Filtering-Correlation-Id: 5d33e7df-741d-4c1a-9af0-08d342d6af17 X-Microsoft-Exchange-Diagnostics: 1;VI1PR05MB1694;2:gunN8wE2OixyrR5hgJF10Fp0+bHMc5ZzG4njzSv9M4WtCJ3+n2BID9IQfxEpLtUgnRHCkGmG3LiuZ7Eo6W0ipq9Hgza0bh5Pom8Zpu6DNIW3zmghrKlIo3RUzGsKZg78PVXYqqoRRb2HcurIcFXUlp9T3STRSfOQhiSLAWqbwQz3Y77FwhPbGTDQ+/mKEdrA;3:I505eBNYiM/zZPitRS3JkcEXHTrPv06eoo+8lHd7A630MAiqWtrpbQEOdJC+jVhPFjyZDTuh9PCPTj8N0quOzvfIePwLSbBkLm3yg8ObPC7z+kb2RK3S/WUvYE9KYyuaG7YNYBgl4xqNZmSbgvbDM4/zsOWjUY1zwkHzU7ixk6wGZ0gyvEuoL2MYJQP/kkIb;25:iBRYfZUk/xNiWmH0YYwwBZ7Ui5lWTgqDsiwxE6x2XChicQsM0Vj1xlSSzawUeqccyjdG2oksqeBk2Qln2wnpjhC2RmNoUyxAM9EPKaAkBMYLNCmaMh6TkC6u/nKa4r8NsSWZYPMA3Suv8o2D7sJVddf0O+apNND3lDTrXDv1eZJTY7cxhsiOPVZClmKxY/10UxyUrdAQ3+BVkpMAuV/WLDXIm4lewtjqvKE/ODrTQxWF04y1wqN70qIpryFgJA3EI4owzrbH2AYnQ71ub+XpxnNZwqDavSP36TdN3ydV/7ZoXxas0j1fw4qW+OGPKTBxD+rMr2jjnfVPZ/RrPG6SrVnwwItO0bJZwMB7ucW789A= X-Microsoft-Antispam: UriScan:;BCL:0;PCL:0;RULEID:;SRVR:VI1PR05MB1694; X-MLNXRule-EZCH-Linux: Rule triggered X-MLNXRule-Acc-Dom-4: Rule triggered X-Microsoft-Exchange-Diagnostics: 1;VI1PR05MB1694;20:0K5JfkU1bUSBDluXc1NudgfRth44Anl9e84WHZAqTEK/v3WMdplOUhfAjVwLv9JIceGwu3ioMqCeOrFkfWWowN1xXejSdWui7+C3j2RyrK1cl9bfkCjer0nHVFZshZg0Qwx94BwLHTX9wkaxZxqTldjXJ2yoxDN3XIB6OTIladrEXboozjpKjN66ur14mMWUdPTo+s5EyLnd+9p7eJjIfsv2ceFnnX6f/U6gfXOVNw1mjnsLXUinSaAU7Z/AaxHzRgYEcXraxKa9dK83clElEK73QCI6xdUpWt5F3u3vTlET0l7domt9PM1JdGEn7EQxrNBagapMEhPeDfcRSkeFrG6LnFnqkHdylr/TnKul8fhP3ppCBrxRonyBS12i0mR3IyhZt/bof46PQm/8McNqD4C9S9rU0NiYcBLxHy1GZ1utjXzDSCiESu2/DmwfRUsC/erVzkoMTUoBjCYLvfyrYrPZpvbEjwqgZ7b9kjwBJk0HYvFe+hLSxSsj8i+W0CfQfns8sZRnNck+ecPb0WNB6rftGoov65bpVoBV1gjOLj/3lDn9AAbwwEda52+kg0bBHy3tupfV0uoFTgUFD+ivLZNoEmHLeu0GYRgKcR363mA= X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(601004)(2401047)(13015025)(13017025)(13023025)(13024025)(5005006)(8121501046)(13018025)(3002001)(10201501046);SRVR:VI1PR05MB1694;BCL:0;PCL:0;RULEID:;SRVR:VI1PR05MB1694; X-Microsoft-Exchange-Diagnostics: 1;VI1PR05MB1694;4:GrigJ0WjNPYYN61ygokdWWjPeTuMB0txoLWlhcomxT54hBe2L0ZW3ILwwyE2ojiVfL9/+puNyziDf3aA+6NEGjzXu4kfiFTvDDZnmZvGM/6GaSpra+8NtxdwfqGLThwlLzRV1NgbW1i8mMx/9mrnGiVecRDJWD1SxExsDrNFWhkQJF0z9yXm5sEpoSADgFOfsa6h8BpeucDctFdwY0CreiQlC7i9aaRkP7PPRT54ep8fB43zvJCa1XPqFYOWFPe8K9aw1DvQK/F4S4+d8cva3Ztqavz7PDJBvFaKmaG47EzW4Ef12xagGP7Osn4kj97IvlMZqMpnw2J0P0gpB57mAVI+ZPIEin97T4amRV2sA9zT0hjE19/3mi19j7sINNPR9CC3/g+MDeeCE1VnrBnEU0QFXAWzmiJwQGWGzFl192cjb+/z6/xE5vcplwVOsWzhzrPLI+9A9sl/qFQK8NxEiQ== X-Forefront-PRVS: 086943A159 X-Microsoft-Exchange-Diagnostics: =?us-ascii?Q?1;VI1PR05MB1694;23:py0rwS1gXB01+byAtUDbrYWuBbW2DPBomLlqeE6lJ?= =?us-ascii?Q?gPAtizCF99+LP4ngQ+03n8yxns6wOi4NFLelEMsSrrImBi0CweSbqwo6uJwJ?= =?us-ascii?Q?31Rs6K1WQ7w2HjpSyMcNaCKoHuukFy/JiJHLcJyF61Nnk93ITtABK3b4zUZ3?= =?us-ascii?Q?/JVMYoiPTu7NyUzyRt4vwOiODteDsG23s8/zl3QLfgxvnL5Utjv3FQp0nfKe?= =?us-ascii?Q?aFMip3Z0aRQgFdCCAInSjWM6Bpi2AKtH34XXXicYCZvBK7j0HGzv9XoKeiGC?= =?us-ascii?Q?npzgADrBYYU/tIULxKd1P2zBGCeC91GPDLMBMVD2G73HZHJAYg/6Cf/O4/yV?= =?us-ascii?Q?rHC+UCVFgryQtiXrpk49mDF6xEOnfmuW6cpbVzHhQIKfY/m9yhXD5Nh/CGpf?= =?us-ascii?Q?jeo9IGBxRkh/D44NULaCtmiWWfDTy39RReHqK47QFIKFHtm9IqmMWYypdk2M?= =?us-ascii?Q?a4l1319lI1pyZ7lkuj46v0E6miYexBwdMgHI0PaOLg/jl/E3+7RA+XaLAE3z?= =?us-ascii?Q?FWf2kl42KufkjChsbgtv5dhquQhPIHpdRHkbw7MdGokGE8tLtc/7fs2UQBPL?= =?us-ascii?Q?hRDdpGclDh4B6nGDfFEVo6AVXmtpyoEtTIUgl63ymvL1/XpXy4MviEIoM08c?= =?us-ascii?Q?QDUv7nc1DsTFEpTmp9EcBHoUmnES0SX+Qks1FPmdGEjTGtDvs1R+yii5Y8nF?= =?us-ascii?Q?F2RDALKwxTuo0z3ZMrsaYqwlXoj837MoqZv/uvGyyQPwvO3HqQlGGpzr3SmZ?= =?us-ascii?Q?Dhm4ZOyKqymcP29tbHv1s3+Kt+aluQOyh5HGmW2qLWSiPCUoSO/+WxWAyRl7?= =?us-ascii?Q?20cz6e1jy5zWCrKK49dFIeZhVH2YIfCraTtntxMireAq2pK61eF/8PQiDfTm?= =?us-ascii?Q?frvm0xlgWIkHbVNWcyUSeCwrLTpYo0sSwL7hNNAwhDPVfTUPHnQUlQCoyRAz?= =?us-ascii?Q?wMk91/YgoKq9u/wVUh3V1G9AOy4zM+sKmr9UsQ7dSLTCRhnPx9RVwA18Jzkd?= =?us-ascii?Q?rM8XEDdEKkUjeDurGLtviu0ARz8sxkR9ZKVVaF31UrdvANvYSxpmc3fUADjr?= =?us-ascii?Q?wjS+CgSQDQkreCvg9+vrCU6C/Fq0IiWd+bLu5iOKvKa91nGmDIBQRttaAg0a?= =?us-ascii?Q?Sb7XCqG28QO27mT7tEJ646VKySYZU+9q8PZg+1+ZkynwPf55ANTj6eDZaK8Z?= =?us-ascii?Q?bFZfItaS/sciXVWlOZlLx9ouTzhLjuqPpD412hLgtL1yfYPFQbSsjMc/LK0r?= =?us-ascii?Q?Kc9/BhCxV7w4Fp5mZ0ZZDUfgqKh1S5DMjJ7d7q79m2Zutjkz/TFQ2ZaEnkfS?= =?us-ascii?Q?eeqRGiZ8hJqXMhpEfTZpaaN9kpCg9rJ8Ikh8dTUHlPt?= X-Microsoft-Exchange-Diagnostics: 1;VI1PR05MB1694;5:xgBe+5/nJLlsdCcj8k8p1rB8HTW8VC+aHzFHLw8RR6dhBEMI0CL6KosQqv+kUai61lq4OOH0v++n/p1L8U6677f8BEeey3BDzioclZOnkZ4u1ZevCX8+1XiGT6UJlL7oD1V0dVPYKqzGpYsOhpZtdw==;24:QmyX0DYYD9aSJrD1kF1RmjlIJMbOyLIIwwL0Wzxu3wqnDEoCy4zBxf+tcOvE7nbWngM/hyTUMN8+ePUwLrn1QRTuOBLOyhP+CpV59y823lU= X-OriginatorOrg: ezchip.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 02 Mar 2016 20:10:21.2842 (UTC) X-MS-Exchange-CrossTenant-Id: a652971c-7d2e-4d9b-a6a4-d149256f461b X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=a652971c-7d2e-4d9b-a6a4-d149256f461b;Ip=[12.216.194.146];Helo=[ld-1.internal.tilera.com] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: VI1PR05MB1694 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 11580 Lines: 349 The new "task_isolation_debug" flag simplifies debugging of TASK_ISOLATION kernels when processes are running in PR_TASK_ISOLATION_ENABLE mode. Such processes should get no interrupts from the kernel, and if they do, when this boot flag is specified a kernel stack dump on the console is generated. It's possible to use ftrace to simply detect whether a task_isolation core has unexpectedly entered the kernel. But what this boot flag does is allow the kernel to provide better diagnostics, e.g. by reporting in the IPI-generating code what remote core and context is preparing to deliver an interrupt to a task_isolation core. It may be worth considering other ways to generate useful debugging output rather than console spew, but for now that is simple and direct. Signed-off-by: Chris Metcalf --- Documentation/kernel-parameters.txt | 8 ++++ include/linux/context_tracking_state.h | 6 +++ include/linux/isolation.h | 5 +++ kernel/irq_work.c | 5 ++- kernel/isolation.c | 77 ++++++++++++++++++++++++++++++++++ kernel/sched/core.c | 18 ++++++++ kernel/signal.c | 5 +++ kernel/smp.c | 6 ++- kernel/softirq.c | 33 +++++++++++++++ 9 files changed, 161 insertions(+), 2 deletions(-) diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index c8d0b42d984a..ea0434fa906e 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt @@ -3755,6 +3755,14 @@ bytes respectively. Such letter suffixes can also be entirely omitted. also sets up nohz_full and isolcpus mode for the listed set of cpus. + task_isolation_debug [KNL] + In kernels built with CONFIG_TASK_ISOLATION + and booted in task_isolation= mode, this + setting will generate console backtraces when + the kernel is about to interrupt a task that + has requested PR_TASK_ISOLATION_ENABLE and is + running on a task_isolation core. + tcpmhash_entries= [KNL,NET] Set the number of tcp_metrics_hash slots. Default value is 8192 or 16384 depending on total diff --git a/include/linux/context_tracking_state.h b/include/linux/context_tracking_state.h index 1d34fe68f48a..4e2c4b900b82 100644 --- a/include/linux/context_tracking_state.h +++ b/include/linux/context_tracking_state.h @@ -39,8 +39,14 @@ static inline bool context_tracking_in_user(void) { return __this_cpu_read(context_tracking.state) == CONTEXT_USER; } + +static inline bool context_tracking_cpu_in_user(int cpu) +{ + return per_cpu(context_tracking.state, cpu) == CONTEXT_USER; +} #else static inline bool context_tracking_in_user(void) { return false; } +static inline bool context_tracking_cpu_in_user(int cpu) { return false; } static inline bool context_tracking_active(void) { return false; } static inline bool context_tracking_is_enabled(void) { return false; } static inline bool context_tracking_cpu_is_enabled(void) { return false; } diff --git a/include/linux/isolation.h b/include/linux/isolation.h index ba6c4d510db8..f1ae7b663746 100644 --- a/include/linux/isolation.h +++ b/include/linux/isolation.h @@ -45,6 +45,9 @@ static inline void task_isolation_enter(void) extern bool task_isolation_syscall(int nr); extern void task_isolation_exception(const char *fmt, ...); extern void task_isolation_interrupt(struct task_struct *, const char *buf); +extern void task_isolation_debug(int cpu); +extern void task_isolation_debug_cpumask(const struct cpumask *); +extern void task_isolation_debug_task(int cpu, struct task_struct *p); static inline bool task_isolation_strict(void) { @@ -73,6 +76,8 @@ static inline bool task_isolation_ready(void) { return true; } static inline void task_isolation_enter(void) { } static inline bool task_isolation_check_syscall(int nr) { return false; } static inline void task_isolation_check_exception(const char *fmt, ...) { } +static inline void task_isolation_debug(int cpu) { } +#define task_isolation_debug_cpumask(mask) do {} while (0) #endif #endif diff --git a/kernel/irq_work.c b/kernel/irq_work.c index bcf107ce0854..a9b95ce00667 100644 --- a/kernel/irq_work.c +++ b/kernel/irq_work.c @@ -17,6 +17,7 @@ #include #include #include +#include #include @@ -75,8 +76,10 @@ bool irq_work_queue_on(struct irq_work *work, int cpu) if (!irq_work_claim(work)) return false; - if (llist_add(&work->llnode, &per_cpu(raised_list, cpu))) + if (llist_add(&work->llnode, &per_cpu(raised_list, cpu))) { + task_isolation_debug(cpu); arch_send_call_function_single_ipi(cpu); + } return true; } diff --git a/kernel/isolation.c b/kernel/isolation.c index 5621fdf15b17..6ac35988b49a 100644 --- a/kernel/isolation.c +++ b/kernel/isolation.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include "time/tick-sched.h" @@ -182,3 +183,79 @@ bool task_isolation_syscall(int syscall) task_isolation_exception("syscall %d", syscall); return true; } + +/* Enable debugging of any interrupts of task_isolation cores. */ +static int task_isolation_debug_flag; +static int __init task_isolation_debug_func(char *str) +{ + task_isolation_debug_flag = true; + return 1; +} +__setup("task_isolation_debug", task_isolation_debug_func); + +void task_isolation_debug_task(int cpu, struct task_struct *p) +{ + static DEFINE_RATELIMIT_STATE(console_output, HZ, 1); + bool force_debug = false; + + /* + * Our caller made sure the task was running on a task isolation + * core, but make sure the task has enabled isolation. + */ + if (!(p->task_isolation_flags & PR_TASK_ISOLATION_ENABLE)) + return; + + /* + * Ensure the task is actually in userspace; if it is in kernel + * mode, it is expected that it may receive interrupts, and in + * any case they don't affect the isolation. Note that there + * is a race condition here as a task may have committed + * to returning to user space but not yet set the context + * tracking state to reflect it, and the check here is before + * we trigger the interrupt, so we might fail to warn about a + * legitimate interrupt. However, the race window is narrow + * and hitting it does not cause any incorrect behavior other + * than failing to send the warning. + */ + if (!context_tracking_cpu_in_user(cpu)) + return; + + /* + * If the task was in strict mode, deliver a signal to it. + * We disable task isolation mode when we deliver a signal + * so we won't end up recursing back here again. + * If we are in an NMI, we don't try delivering the signal + * and instead just treat it as if "debug" mode was enabled, + * since that's pretty much all we can do. + */ + if (p->task_isolation_flags & PR_TASK_ISOLATION_STRICT) { + if (in_nmi()) + force_debug = true; + else + task_isolation_interrupt(p, "interrupt"); + } + + /* + * If (for example) the timer interrupt starts ticking + * unexpectedly, we will get an unmanageable flow of output, + * so limit to one backtrace per second. + */ + if (force_debug || + (task_isolation_debug_flag && __ratelimit(&console_output))) { + pr_err("Interrupt detected for task_isolation cpu %d, %s/%d\n", + cpu, p->comm, p->pid); + dump_stack(); + } +} + +void task_isolation_debug_cpumask(const struct cpumask *mask) +{ + int cpu, thiscpu = get_cpu(); + + /* No need to report on this cpu since we're already in the kernel. */ + for_each_cpu(cpu, mask) + if (cpu != thiscpu) + task_isolation_debug(cpu); + + put_cpu(); +} diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 9503d590e5ef..f53e1417aa75 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c @@ -74,6 +74,7 @@ #include #include #include +#include #include #include @@ -746,6 +747,23 @@ bool sched_can_stop_tick(void) } #endif /* CONFIG_NO_HZ_FULL */ +#ifdef CONFIG_TASK_ISOLATION +void task_isolation_debug(int cpu) +{ + struct task_struct *p; + + if (!task_isolation_possible(cpu)) + return; + + rcu_read_lock(); + p = cpu_curr(cpu); + get_task_struct(p); + rcu_read_unlock(); + task_isolation_debug_task(cpu, p); + put_task_struct(p); +} +#endif + void sched_avg_update(struct rq *rq) { s64 period = sched_avg_period(); diff --git a/kernel/signal.c b/kernel/signal.c index 0508544c8ced..b35ce19c01c4 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -638,6 +638,11 @@ int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info) */ void signal_wake_up_state(struct task_struct *t, unsigned int state) { +#ifdef CONFIG_TASK_ISOLATION + /* If the task is being killed, don't complain about task_isolation. */ + if (state & TASK_WAKEKILL) + t->task_isolation_flags = 0; +#endif set_tsk_thread_flag(t, TIF_SIGPENDING); /* * TASK_WAKEKILL also means wake it up in the stopped/traced/killable diff --git a/kernel/smp.c b/kernel/smp.c index d903c02223af..a61894409645 100644 --- a/kernel/smp.c +++ b/kernel/smp.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "smpboot.h" @@ -178,8 +179,10 @@ static int generic_exec_single(int cpu, struct call_single_data *csd, * locking and barrier primitives. Generic code isn't really * equipped to do the right thing... */ - if (llist_add(&csd->llist, &per_cpu(call_single_queue, cpu))) + if (llist_add(&csd->llist, &per_cpu(call_single_queue, cpu))) { + task_isolation_debug(cpu); arch_send_call_function_single_ipi(cpu); + } return 0; } @@ -457,6 +460,7 @@ void smp_call_function_many(const struct cpumask *mask, } /* Send a message to all CPUs in the map */ + task_isolation_debug_cpumask(cfd->cpumask); arch_send_call_function_ipi_mask(cfd->cpumask); if (wait) { diff --git a/kernel/softirq.c b/kernel/softirq.c index 479e4436f787..f249b71cddf4 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c @@ -26,6 +26,7 @@ #include #include #include +#include #define CREATE_TRACE_POINTS #include @@ -319,6 +320,37 @@ asmlinkage __visible void do_softirq(void) local_irq_restore(flags); } +/* Determine whether this IRQ is something task isolation cares about. */ +static void task_isolation_irq(void) +{ +#ifdef CONFIG_TASK_ISOLATION + struct pt_regs *regs; + + if (!context_tracking_cpu_is_enabled()) + return; + + /* + * We have not yet called __irq_enter() and so we haven't + * adjusted the hardirq count. This test will allow us to + * avoid false positives for nested IRQs. + */ + if (in_interrupt()) + return; + + /* + * If we were already in the kernel, not from an irq but from + * a syscall or synchronous exception/fault, this test should + * avoid a false positive as well. Note that this requires + * architecture support for calling set_irq_regs() prior to + * calling irq_enter(), and if it's not done consistently, we + * will not consistently avoid false positives here. + */ + regs = get_irq_regs(); + if (regs && user_mode(regs)) + task_isolation_debug(smp_processor_id()); +#endif +} + /* * Enter an interrupt context. */ @@ -335,6 +367,7 @@ void irq_enter(void) _local_bh_enable(); } + task_isolation_irq(); __irq_enter(); } -- 2.1.2