From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752721AbcHLQQR (ORCPT ); Fri, 12 Aug 2016 12:16:17 -0400 Received: from mx1.redhat.com ([209.132.183.28]:50486 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752301AbcHLQQP (ORCPT ); Fri, 12 Aug 2016 12:16:15 -0400 Date: Fri, 12 Aug 2016 18:16:12 +0200 From: Oleg Nesterov To: Bart Van Assche Cc: Peter Zijlstra , "mingo@kernel.org" , Andrew Morton , Johannes Weiner , Neil Brown , Michael Shaver , "linux-kernel@vger.kernel.org" Subject: Re: [PATCH] sched: Avoid that __wait_on_bit_lock() hangs Message-ID: <20160812161611.GC30930@redhat.com> References: <16207b90-2e6c-fe23-1b4b-3763e5cf0384@sandisk.com> <20160808102213.GA6879@twins.programming.kicks-ass.net> <4091e252-18d9-1795-de63-9fbc678aa6b1@acm.org> <20160808162038.GA25927@redhat.com> <78fafdc1-d4ae-a9a2-169c-1d456b6e6e41@sandisk.com> <20160809171459.GA13840@redhat.com> <3cec7657-caa9-92ca-9f0e-34f073a6ed8c@sandisk.com> <20160810104555.GA3333@redhat.com> <4d2e02f8-c7da-ee1a-1068-25492cbffebe@sandisk.com> <20160811173651.GA31803@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20160811173651.GA31803@redhat.com> User-Agent: Mutt/1.5.24 (2015-08-30) X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.39]); Fri, 12 Aug 2016 16:16:15 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 08/11, Oleg Nesterov wrote: > > I'll send another debugging patch tomorrow, I was a bit busy today. The next > step is obvious, we need to know the caller. Please drop two patches I sent before anf try the new one below. Which kernel version do you use? Oleg. --- diff --git a/include/linux/page-flags.h b/include/linux/page-flags.h index e5a3244..533da3ab 100644 --- a/include/linux/page-flags.h +++ b/include/linux/page-flags.h @@ -711,6 +711,15 @@ static inline int page_has_private(struct page *page) return !!(page->flags & PAGE_FLAGS_PRIVATE); } +void unlock_page_x(struct page *page); +static inline void __ClearPageLocked_x(struct page *page) +{ + if (PageLocked(compound_head(page))) + unlock_page_x(page); +} + +#define __ClearPageLocked(page) __ClearPageLocked_x(page) + #undef PF_ANY #undef PF_HEAD #undef PF_NO_TAIL diff --git a/mm/filemap.c b/mm/filemap.c index 20f3b1f..fb320fb 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -837,6 +837,43 @@ void unlock_page(struct page *page) } EXPORT_SYMBOL(unlock_page); +void unlock_page_x(struct page *__page) +{ + struct page *page = compound_head(__page); + wait_queue_head_t *wq = page_waitqueue(page); + struct wait_bit_key key = __WAIT_BIT_KEY_INITIALIZER(&page->flags, PG_locked); + wait_queue_t *curr, *next; + unsigned long flags; + bool w = false; + + #define W() do { \ + if (!w) { w = true; pr_crit("XXXXXXXXXXXX\n"); dump_stack(); } \ + } while (0) + + clear_bit_unlock(PG_locked, &page->flags); + smp_mb__after_atomic(); + + if (!waitqueue_active(wq)) + return; + + spin_lock_irqsave(&wq->lock, flags); + list_for_each_entry_safe(curr, next, &wq->task_list, task_list) { + if (curr->func == wake_bit_function) { + struct wait_bit_queue *wb = container_of(curr, struct wait_bit_queue, wait); + if (wb->key.flags == key.flags && wb->key.bit_nr == PG_locked) { + W(); + pr_crit("XXX flags = %x, waiter:\n", curr->flags); + sched_show_task(curr->private); + } + } else { + W(); + pr_crit("XXX flags = %x, func = %pF\n", curr->flags, curr->func); + } + curr->func(curr, TASK_NORMAL, 0, &key); + } + spin_unlock_irqrestore(&wq->lock, flags); +} + /** * end_page_writeback - end writeback against a page * @page: the page