Received: by 2002:a25:ad19:0:0:0:0:0 with SMTP id y25csp794148ybi; Wed, 17 Jul 2019 05:03:34 -0700 (PDT) X-Google-Smtp-Source: APXvYqwafKE+jFYSIEdMtod796rfsFnns5ahQR/3n2V7R2Y+yhau/cAffDhy2tqdHAmnPciS3boj X-Received: by 2002:a17:902:b702:: with SMTP id d2mr43999826pls.259.1563365014480; Wed, 17 Jul 2019 05:03:34 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1563365014; cv=none; d=google.com; s=arc-20160816; b=ho04bXbInhs2TLMRM/hZP+u6U6HRCvVxycjqVbqKP4Ds2bh8O5DUm/WLqyUMSIcLSh 5spfZtscMSWM4xiJ8DDTfQuuuMZxanXcj7681DoVqzeM8fJFq9YQyNzPZbSNh2XXtSx0 7NusMx6M3/0lT1dqsGCaA84i+YjoWSfVdKrtVFg+Qt5NmlfQiw+n4gFbep8aHvxIxDfW rLV4sy1yGyBmpEDTSDV9ZIvEPrmoUZONBEeOkHKIlgBTM8u8YkkkVNMVIB6PBJedXBTf dPH9ffCvnpYz4wXxdUMdtSpJy15HUAGvBX2zSP72lW2lFBipe4IxgX/VwiepoDU+j63W pxYw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from; bh=3J5Hgv+6mxY/IiDn6ocUJMauTHw9xo1hCvFLRMBRGpw=; b=fU/3Pqfscl/qjOmlPmkMNhIgNLPIUDRVrgGFfL125i4js7LHJe52R7P4M0plKIIU54 9AyVh+9XXJW23zHBUUNqwNfxeaNd28MNKlACIkpX/gERS6WM6i/mwVi+fY1Deo4kczdM gD+JWQxeQUUvP65fai6FQhrskzMOqjL0stcxmh7+uZbjo7zDka8JzICt1K2Nh+MMYJf1 qMcJoPby1Nj+36/83MeQJrqvC7IsVoPZcHx8vmoPiMdq2jV1Na60Gub/6IvWHw8Pnvay nrT9oxnOzkenWk13jdOVG4O7sgKp6eD3N+Pyo0/PbXySinf9ptfoEPRI6LKFYbuptJyA oeOg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id d7si21855856pgc.470.2019.07.17.05.03.17; Wed, 17 Jul 2019 05:03:34 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726831AbfGQMCe (ORCPT + 99 others); Wed, 17 Jul 2019 08:02:34 -0400 Received: from mx1.redhat.com ([209.132.183.28]:41516 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725906AbfGQMCe (ORCPT ); Wed, 17 Jul 2019 08:02:34 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 1FDE78665F; Wed, 17 Jul 2019 12:02:34 +0000 (UTC) Received: from dustball.brq.redhat.com (unknown [10.43.17.163]) by smtp.corp.redhat.com (Postfix) with ESMTP id 38A465D9CA; Wed, 17 Jul 2019 12:02:30 +0000 (UTC) From: Jan Stancek To: linux-kernel@vger.kernel.org Cc: longman@redhat.com, dbueso@suse.de, will@kernel.org, peterz@infradead.org, mingo@redhat.com, jstancek@redhat.com Subject: [PATCH v2] locking/rwsem: add acquire barrier to read_slowpath exit when queue is empty Date: Wed, 17 Jul 2019 14:02:20 +0200 Message-Id: In-Reply-To: <20190716185807.GJ3402@hirez.programming.kicks-ass.net> References: <20190716185807.GJ3402@hirez.programming.kicks-ass.net> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.26]); Wed, 17 Jul 2019 12:02:34 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org LTP mtest06 has been observed to rarely hit "still mapped when deleted" and following BUG_ON on arm64: page:ffff7e02fa37e480 refcount:3 mapcount:1 mapping:ffff80be3d678ab0 index:0x0 xfs_address_space_operations [xfs] flags: 0xbfffe000000037(locked|referenced|uptodate|lru|active) page dumped because: VM_BUG_ON_PAGE(page_mapped(page)) ------------[ cut here ]------------ kernel BUG at mm/filemap.c:171! Internal error: Oops - BUG: 0 [#1] SMP CPU: 220 PID: 154292 Comm: mmap1 Not tainted 5.2.0-0ecfebd.cki #1 Hardware name: HPE Apollo 70 /C01_APACHE_MB , BIOS L50_5.13_1.10 05/17/2019 pstate: 40400089 (nZcv daIf +PAN -UAO) pc : unaccount_page_cache_page+0x17c/0x1a0 lr : unaccount_page_cache_page+0x17c/0x1a0 Call trace: unaccount_page_cache_page+0x17c/0x1a0 delete_from_page_cache_batch+0xa0/0x300 truncate_inode_pages_range+0x1b8/0x640 truncate_inode_pages_final+0x88/0xa8 evict+0x1a0/0x1d8 iput+0x150/0x240 dentry_unlink_inode+0x120/0x130 __dentry_kill+0xd8/0x1d0 dentry_kill+0x88/0x248 dput+0x168/0x1b8 __fput+0xe8/0x208 ____fput+0x20/0x30 task_work_run+0xc0/0xf0 do_notify_resume+0x2b0/0x328 work_pending+0x8/0x10 The extra mapcount originated from pagefault handler, which handled pagefault for vma that has already been detached. vma is detached under mmap_sem write lock by detach_vmas_to_be_unmapped(), which also invalidates vmacache. When pagefault handler (under mmap_sem read lock) called find_vma(), vmacache_valid() wrongly reported vmacache as valid. After rwsem down_read() returns via 'queue empty' path (as of v5.2), it does so without issuing read_acquire on sem->count: down_read __down_read rwsem_down_read_failed __rwsem_down_read_failed_common raw_spin_lock_irq(&sem->wait_lock); if (list_empty(&sem->wait_list)) { if (atomic_long_read(&sem->count) >= 0) { raw_spin_unlock_irq(&sem->wait_lock); return sem; Suspected problem here is that last *_acquire on down_read() side happens before write side issues *_release: 1. writer: has the lock 2. reader: down_read() issues *read_acquire on entry 3. writer: mm->vmacache_seqnum++; downgrades lock (*fetch_add_release) 4. reader: __rwsem_down_read_failed_common() finds it can take lock and returns 5. reader: observes stale mm->vmacache_seqnum I can reproduce the problem by running LTP mtest06 in a loop and building kernel (-j $NCPUS) in parallel. It does reproduce since v4.20 up to v5.2 on arm64 HPE Apollo 70 (224 CPUs, 256GB RAM, 2 nodes). It triggers reliably within ~hour. Patched kernel ran fine for 10+ hours with clean dmesg. Tests were done against v5.2, since commit cf69482d62d9 ("locking/rwsem: Enable readers spinning on writer") makes it much harder to reproduce. v2: Move barrier after test (Waiman Long) Use smp_acquire__after_ctrl_dep() (Peter Zijlstra) Related: https://github.com/linux-test-project/ltp/blob/master/testcases/kernel/mem/mtest06/mmap1.c Related: commit dd2283f2605e ("mm: mmap: zap pages with read mmap_sem in munmap") Fixes: 4b486b535c33 ("locking/rwsem: Exit read lock slowpath if queue empty & no writer") Signed-off-by: Jan Stancek Cc: stable@vger.kernel.org # v4.20+ Cc: Waiman Long Cc: Davidlohr Bueso Cc: Will Deacon Cc: Peter Zijlstra Cc: Ingo Molnar --- kernel/locking/rwsem.c | 1 + 1 file changed, 1 insertion(+) diff --git a/kernel/locking/rwsem.c b/kernel/locking/rwsem.c index 37524a47f002..5ac72b60608b 100644 --- a/kernel/locking/rwsem.c +++ b/kernel/locking/rwsem.c @@ -1032,6 +1032,7 @@ static inline bool rwsem_reader_phase_trylock(struct rw_semaphore *sem, */ if (adjustment && !(atomic_long_read(&sem->count) & (RWSEM_WRITER_MASK | RWSEM_FLAG_HANDOFF))) { + smp_acquire__after_ctrl_dep(); raw_spin_unlock_irq(&sem->wait_lock); rwsem_set_reader_owned(sem); lockevent_inc(rwsem_rlock_fast); -- 1.8.3.1