From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id B6192EDE9B6 for ; Thu, 14 Sep 2023 12:21:56 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id B5AB06B0182; Thu, 14 Sep 2023 08:21:55 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id B059E6B018A; Thu, 14 Sep 2023 08:21:55 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 9D0606B0194; Thu, 14 Sep 2023 08:21:55 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0010.hostedemail.com [216.40.44.10]) by kanga.kvack.org (Postfix) with ESMTP id 86AD26B0182 for ; Thu, 14 Sep 2023 08:21:55 -0400 (EDT) Received: from smtpin09.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay04.hostedemail.com (Postfix) with ESMTP id 49E2E1A04E1 for ; Thu, 14 Sep 2023 12:21:55 +0000 (UTC) X-FDA: 81235114590.09.8CA97EF Received: from r3-25.sinamail.sina.com.cn (r3-25.sinamail.sina.com.cn [202.108.3.25]) by imf11.hostedemail.com (Postfix) with ESMTP id 89EB540019 for ; Thu, 14 Sep 2023 12:21:51 +0000 (UTC) Authentication-Results: imf11.hostedemail.com; dkim=none; dmarc=none; spf=pass (imf11.hostedemail.com: domain of hdanton@sina.com designates 202.108.3.25 as permitted sender) smtp.mailfrom=hdanton@sina.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1694694113; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=n3td66dBknR1wbAxUNdivzsJZitEZeAJN+I60eTXSLw=; b=IMBpnRpMkIfwYDrLESAdjj1gtilA/oCGM6AKpXfdP4Myc3Jd7nA4pf6zabpErUvDHktDnp 59zUfHHPGlIig++5f9GcNTNPumoCkBu6zhXfqaZptjQqmv9vuYm0v/XuRtkclPF/vJw96L PN/IswMHbHworuCYHenX5pgIJwMlEw4= ARC-Authentication-Results: i=1; imf11.hostedemail.com; dkim=none; dmarc=none; spf=pass (imf11.hostedemail.com: domain of hdanton@sina.com designates 202.108.3.25 as permitted sender) smtp.mailfrom=hdanton@sina.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1694694113; a=rsa-sha256; cv=none; b=r/LLRlFoBVx6xlulLuFD+B8xSo3i8C4VbJjO7h3h4FhxGRBv0Y82CQwJDAwolKKJkzD4SU I30PMSD9F7R02JNh3sM30Xin9oQgErxOVQydWWB14w4XBgW+qdKweL0FEwBO6ACtTP9k9Z 0ts+K0fIHGSWLhdZL8d2w+nDYTY7e/k= X-SMAIL-HELO: localhost.localdomain Received: from unknown (HELO localhost.localdomain)([112.97.59.200]) by sina.com (172.16.97.23) with ESMTP id 6502FAD700035A17; Thu, 14 Sep 2023 20:21:46 +0800 (CST) X-Sender: hdanton@sina.com X-Auth-ID: hdanton@sina.com X-SMAIL-MID: 45252531457908 X-SMAIL-UIID: 5A3B5CE8BFF4473B8B2194BCDB1DC5F5-20230914-202146-1 From: Hillf Danton To: Tetsuo Handa Cc: Sanan Hasanov , Thomas Gleixner , Linus Torvalds , syzkaller@googlegroups.com, linux-mm@kvack.org, LKML Subject: Re: BUG: soft lockup in smp_call_function Date: Thu, 14 Sep 2023 20:21:34 +0800 Message-Id: <20230914122134.6783-1-hdanton@sina.com> In-Reply-To: <15f8fbd8-2dbc-3df7-c748-c76e3479e227@I-love.SAKURA.ne.jp> References: <20230913110709.6684-1-hdanton@sina.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Rspam-User: X-Stat-Signature: 37auaxbjar6wbsbzqzzcpkq397aacg6s X-Rspamd-Server: rspam07 X-Rspamd-Queue-Id: 89EB540019 X-HE-Tag: 1694694111-721547 X-HE-Meta: U2FsdGVkX180BuFGtdufk5tBDi9BvdnE+zwIRb+V6U4i6LA8tGze5Wwq4j9r3xYpVPU/dCZ6eQqnGV4t5uiD0K0TA4K8/dLLF7BNjmxrmTDUGm2rPsQkefQ1dxobJAr4KRs30QUBcsfOWYUdVKvoknJqtZgI27ARpGW2vnPMtMxcu7lxDZMFvoHqhnwVLK5b9ZlLnil0bdmMNmxjoMKQqLxU9XA3PdN+/4Hvm8+Hw0HztteZBY4yVcN2HI4N87bfN7uX2IkzxusigMwyRwQtGTaEpk6Sef1OrDvvoXdBxGQT1Pv3fJDdFpuVJrkrcb9jt71uUGNyBhqhrfE4nKEAEb43MiIaO5XvAGCjL1/OWe8+DwmnzcclSYFKFsEzdvc1zIEY1CojGoOR1I6XxAzO5vsolzRzcklCEjkutBBZsnIj2AFP+yWcDy+TSwqgIi4jkHz8vzGFEamdyU71713NW59XpYm9CispKTDcqnBlBA1a5YMOWkwcv7MS5QsbdYlJQzXTh/vcyEn9O9ldSRtCjN09TrzBPTedsIQZAQRNSXG2QW9bnMHcdvZGTOVmp7gvpWj5P5bONygZFc/atB5VP8BrETkPgLDp1lAYRV+wI/I8qWAY3bnJagv5z7cABIyDoYTfidEmNDHvHSrecH0myn4YpOOobt3Oz2REIv+wSNwaSpG11HBrcwTI620mgxihA2ZhRM90QGdaYW7eTja6K0q9KVAKtl5wjHakWyE5d/st8kthx3nDmzIppVRjRHXKuESEfNgk0REMTQlwlcWKkJGFcVp7hh9vC0wRBzvwuTuo1kwTNF4eu448iG0TTd0PzwBaLhUWinsxJTplt1s+r5QF9qp/EjnXClDtwXsZxyL05IIcItmmrUfMmJlkp1NLALj53v2L/QExFqBsu/T42a6/lkcvqZ2q368QIw29Hd1BgECrJPLVpsn7Bs/78cglhEZy0n0GI3cpwoxqlKQ knoHb+Kq YhHPLghEFXZeQVfgwk0xxr3tocRcTATNVSk6zTxqg0T7IaIplOl+TXPQ1Ur8I+PDpTZr/Gl8wqby/FhM1agic7pAmJ2fM0/7XATERMupWE6efxNMmcpFQRox9v4G8uON6rc9L X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: On Wed, 13 Sep 2023 23:30:23 +0900 Tetsuo Handa wrote: > On 2023/09/13 20:07, Hillf Danton wrote: > > > > cpu1 cpu4 (see below) > > ==== ==== > > drm_crtc_vblank_off __run_hrtimer > > spin_lock_irq(&dev->event_lock); > > ... > > drm_handle_vblank > > hrtimer_cancel spin_lock_irqsave(&dev->event_lock, irqflags); > > > > > > Deadlock should have been reported instead provided the lockdep_map in > > struct timer_list were added also to hrtimer, so it is highly appreciated > > if Tetsuo or Thomas adds it before 6.8 or 6.10. > > Not me. ;-) > > Since hrtimer_cancel() retries forever until lock_hrtimer_base() succeeds, > we want to add a lockdep annotation into hrtimer_cancel() so that we can > detect this type of deadlock? Yes, you are right. The diff below is my two cents (only for thoughts). --- x/include/linux/timer.h +++ y/include/linux/timer.h @@ -124,6 +124,9 @@ struct hrtimer { u8 is_rel; u8 is_soft; u8 is_hard; +#ifdef CONFIG_LOCKDEP + struct lockdep_map lockdep_map; +#endif }; /** @@ -369,33 +372,65 @@ static inline void hrtimer_cancel_wait_r /* Exported timer functions: */ /* Initialize timers: */ -extern void hrtimer_init(struct hrtimer *timer, clockid_t which_clock, - enum hrtimer_mode mode); -extern void hrtimer_init_sleeper(struct hrtimer_sleeper *sl, clockid_t clock_id, - enum hrtimer_mode mode); +extern void hrtimer_init_key(struct hrtimer *timer, clockid_t which_clock, + enum hrtimer_mode mode, + const char *name, struct lock_class_key *key); +extern void hrtimer_init_sleeper_key(struct hrtimer_sleeper *sl, clockid_t clock_id, + enum hrtimer_mode mode, + const char *name, struct lock_class_key *key); +#ifdef CONFIG_LOCKDEP +#define hrtimer_init(t, c, m) \ + do { \ + static struct lock_class_key __key; \ + hrtimer_init_key(t, c, m, #t, &__key); \ + } while (0) + +#define hrtimer_init_sleeper(s, c, m) \ + do { \ + static struct lock_class_key __key; \ + hrtimer_init_sleeper_key(s, c, m, #s, &__key); \ + } while (0) +#else +#define hrtimer_init(t, c, m) \ + hrtimer_init_key(t, c, m, NULL, NULL) + +#define hrtimer_init_sleeper(s, c, m) \ + hrtimer_init_sleeper_key(s, c, m, NULL, NULL) +#endif #ifdef CONFIG_DEBUG_OBJECTS_TIMERS -extern void hrtimer_init_on_stack(struct hrtimer *timer, clockid_t which_clock, - enum hrtimer_mode mode); -extern void hrtimer_init_sleeper_on_stack(struct hrtimer_sleeper *sl, +extern void hrtimer_init_on_stack_key(struct hrtimer *timer, clockid_t which_clock, + enum hrtimer_mode mode, + const char *name, struct lock_class_key *key); +extern void hrtimer_init_sleeper_on_stack_key(struct hrtimer_sleeper *sl, clockid_t clock_id, - enum hrtimer_mode mode); + enum hrtimer_mode mode, + const char *name, struct lock_class_key *key); +#ifdef CONFIG_LOCKDEP + #define hrtimer_init_on_stack(t, c, m) \ + do { \ + static struct lock_class_key __key; \ + hrtimer_init_on_stack_key(t, c, m, #t, &__key); \ + } while (0) + #define hrtimer_init_sleeper_on_stack(s, c, m) \ + do { \ + static struct lock_class_key __key; \ + hrtimer_init_sleeper_on_stack_key(s, c, m, #s, &__key); \ + } while (0) +#else + #define hrtimer_init_on_stack(t, c, m) \ + hrtimer_init_on_stack_key(t, c, m, NULL, NULL) + #define hrtimer_init_sleeper_on_stack(s, c, m) \ + hrtimer_init_sleeper_on_stack_key(s, c, m, NULL, NULL) +#endif extern void destroy_hrtimer_on_stack(struct hrtimer *timer); #else -static inline void hrtimer_init_on_stack(struct hrtimer *timer, - clockid_t which_clock, - enum hrtimer_mode mode) -{ - hrtimer_init(timer, which_clock, mode); -} +#define hrtimer_init_on_stack(t, c, m) \ + hrtimer_init(t, c, m) -static inline void hrtimer_init_sleeper_on_stack(struct hrtimer_sleeper *sl, - clockid_t clock_id, - enum hrtimer_mode mode) -{ - hrtimer_init_sleeper(sl, clock_id, mode); -} +#define hrtimer_init_sleeper_on_stack(s, c, m) \ + hrtimer_init_sleeper(s, c, m) static inline void destroy_hrtimer_on_stack(struct hrtimer *timer) { } #endif --- x/kernel/time/hrtimer.c +++ y/kernel/time/hrtimer.c @@ -428,22 +428,26 @@ static inline void debug_hrtimer_deactiv static void __hrtimer_init(struct hrtimer *timer, clockid_t clock_id, enum hrtimer_mode mode); -void hrtimer_init_on_stack(struct hrtimer *timer, clockid_t clock_id, - enum hrtimer_mode mode) +void hrtimer_init_on_stack_key(struct hrtimer *timer, clockid_t clock_id, + enum hrtimer_mode mode, + const char *name, struct lock_class_key *key) { debug_object_init_on_stack(timer, &hrtimer_debug_descr); __hrtimer_init(timer, clock_id, mode); + lockdep_init_map(&timer->lockdep_map, name, key, 0); } EXPORT_SYMBOL_GPL(hrtimer_init_on_stack); static void __hrtimer_init_sleeper(struct hrtimer_sleeper *sl, clockid_t clock_id, enum hrtimer_mode mode); -void hrtimer_init_sleeper_on_stack(struct hrtimer_sleeper *sl, - clockid_t clock_id, enum hrtimer_mode mode) +void hrtimer_init_sleeper_on_stack_key(struct hrtimer_sleeper *sl, + clockid_t clock_id, enum hrtimer_mode mode, + const char *name, struct lock_class_key *key) { debug_object_init_on_stack(&sl->timer, &hrtimer_debug_descr); __hrtimer_init_sleeper(sl, clock_id, mode); + lockdep_init_map(&sl->timer.lockdep_map, name, key, 0); } EXPORT_SYMBOL_GPL(hrtimer_init_sleeper_on_stack); @@ -1439,6 +1443,8 @@ int hrtimer_cancel(struct hrtimer *timer { int ret; + lock_map_acquire(&timer->lockdep_map); + lock_map_release(&timer->lockdep_map); do { ret = hrtimer_try_to_cancel(timer); @@ -1586,11 +1592,12 @@ static void __hrtimer_init(struct hrtime * but the PINNED bit is ignored as pinning happens * when the hrtimer is started */ -void hrtimer_init(struct hrtimer *timer, clockid_t clock_id, - enum hrtimer_mode mode) +void hrtimer_init_key(struct hrtimer *timer, clockid_t clock_id, enum hrtimer_mode mode, + const char *name, struct lock_class_key *key) { debug_init(timer, clock_id, mode); __hrtimer_init(timer, clock_id, mode); + lockdep_init_map(&timer->lockdep_map, name, key, 0); } EXPORT_SYMBOL_GPL(hrtimer_init); @@ -1647,6 +1654,11 @@ static void __run_hrtimer(struct hrtimer enum hrtimer_restart (*fn)(struct hrtimer *); bool expires_in_hardirq; int restart; +#ifdef CONFIG_LOCKDEP + struct lockdep_map lockdep_map; + + lockdep_copy_map(&lockdep_map, &timer->lockdep_map); +#endif lockdep_assert_held(&cpu_base->lock); @@ -1682,7 +1694,9 @@ static void __run_hrtimer(struct hrtimer trace_hrtimer_expire_entry(timer, now); expires_in_hardirq = lockdep_hrtimer_enter(timer); + lock_map_acquire(&lockdep_map); restart = fn(timer); + lock_map_release(&lockdep_map); lockdep_hrtimer_exit(expires_in_hardirq); trace_hrtimer_expire_exit(timer); @@ -2004,12 +2018,13 @@ static void __hrtimer_init_sleeper(struc * @clock_id: the clock to be used * @mode: timer mode abs/rel */ -void hrtimer_init_sleeper(struct hrtimer_sleeper *sl, clockid_t clock_id, - enum hrtimer_mode mode) +void hrtimer_init_sleeper_key(struct hrtimer_sleeper *sl, clockid_t clock_id, + enum hrtimer_mode mode, + const char *name, struct lock_class_key *key) { debug_init(&sl->timer, clock_id, mode); __hrtimer_init_sleeper(sl, clock_id, mode); - + lockdep_init_map(&sl->timer.lockdep_map, name, key, 0); } EXPORT_SYMBOL_GPL(hrtimer_init_sleeper); --