From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-yw0-f199.google.com (mail-yw0-f199.google.com [209.85.161.199]) by kanga.kvack.org (Postfix) with ESMTP id A1B456B025F for ; Mon, 7 Aug 2017 21:01:59 -0400 (EDT) Received: by mail-yw0-f199.google.com with SMTP id 7so30932034ywe.0 for ; Mon, 07 Aug 2017 18:01:59 -0700 (PDT) Received: from mail-yw0-x244.google.com (mail-yw0-x244.google.com. [2607:f8b0:4002:c05::244]) by mx.google.com with ESMTPS id b3si28334ybm.434.2017.08.07.18.01.58 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 07 Aug 2017 18:01:58 -0700 (PDT) Received: by mail-yw0-x244.google.com with SMTP id p68so1337278ywg.5 for ; Mon, 07 Aug 2017 18:01:58 -0700 (PDT) From: Bradley Bolen Subject: Re: kernel panic on null pointer on page->mem_cgroup Date: Mon, 7 Aug 2017 21:01:50 -0400 Message-Id: <20170808010150.4155-1-bradleybolen@gmail.com> In-Reply-To: <20170805155241.GA94821@jaegeuk-macbookpro.roam.corp.google.com> References: <20170805155241.GA94821@jaegeuk-macbookpro.roam.corp.google.com> Sender: owner-linux-mm@kvack.org List-ID: To: linux-mm@kvack.org Cc: jaegeuk@kernel.org, Bradley Bolen I am getting a very similar error on v4.11 with an arm64 board. I, too, also see page->mem_cgroup checked to make sure that it is not NULL and then several instructions later it is NULL. It does appear that someone is changing that member without taking the lock. In my setup, I see crash> bt PID: 72 TASK: e1f48640 CPU: 0 COMMAND: "mmcqd/1" #0 [] (__crash_kexec) from [] #1 [] (panic) from [] #2 [] (svcerr_panic) from [] #3 [] (_SvcErr_) from [] #4 [] (die) from [] #5 [] (__do_kernel_fault) from [] #6 [] (do_page_fault) from [] #7 [] (do_DataAbort) from [] pc : [] lr : [] psr: a0000193 sp : c1a19cc8 ip : 00000000 fp : c1a19d04 r10: 0006ae29 r9 : 00000000 r8 : dfbf1800 r7 : dfbf1800 r6 : 00000001 r5 : f3c1107c r4 : e2fb6424 r3 : 00000000 r2 : 00040228 r1 : 221e3000 r0 : a0000113 Flags: NzCv IRQs off FIQs on Mode SVC_32 ISA ARM #8 [] (__dabt_svc) from [] #9 [] (test_clear_page_writeback) from [] #10 [] (end_page_writeback) from [] #11 [] (end_swap_bio_write) from [] #12 [] (bio_endio) from [] #13 [] (dec_pending) from [] #14 [] (clone_endio) from [] #15 [] (bio_endio) from [] #16 [] (crypt_dec_pending [dm_crypt]) from [] #17 [] (crypt_endio [dm_crypt]) from [] #18 [] (bio_endio) from [] #19 [] (blk_update_request) from [] #20 [] (blk_update_bidi_request) from [] #21 [] (blk_end_bidi_request) from [] #22 [] (blk_end_request) from [] #23 [] (mmc_blk_issue_rw_rq) from [] #24 [] (mmc_blk_issue_rq) from [] #25 [] (mmc_queue_thread) from [] #26 [] (kthread) from [] crash> sym c0112540 c0112540 (T) test_clear_page_writeback+512 /kernel-source/include/linux/memcontrol.h: 518 crash> bt 35 PID: 35 TASK: e1d45dc0 CPU: 1 COMMAND: "kswapd0" #0 [] (__schedule) from [] #1 [] (schedule) from [] #2 [] (schedule_timeout) from [] #3 [] (io_schedule_timeout) from [] #4 [] (mempool_alloc) from [] #5 [] (bio_alloc_bioset) from [] #6 [] (get_swap_bio) from [] #7 [] (__swap_writepage) from [] #8 [] (swap_writepage) from [] #9 [] (shmem_writepage) from [] #10 [] (shrink_page_list) from [] #11 [] (shrink_inactive_list) from [] #12 [] (shrink_node_memcg) from [] #13 [] (shrink_node) from [] #14 [] (kswapd) from [] #15 [] (kthread) from [] It appears that uncharge_list() in mm/memcontrol.c is not taking the page lock when it sets mem_cgroup to NULL. I am not familiar with the mm code so I do not know if this is on purpose or not. There is a comment in uncharge_list that makes me believe that the crashing code should not have been running: /* * Nobody should be changing or seriously looking at * page->mem_cgroup at this point, we have fully * exclusive access to the page. */ However, I am new to looking at this area of the kernel so I am not sure. I was able to create a reproducible scenario by using a udelay to increase the time between the if (page->mem_cgroup) check and the later dereference of it to increase the race window. I then mounted an empty ext4 partition and ran the following no more than twice before it crashed. dd if=/dev/zero of=/tmp/ext4disk/test bs=1M count=100 I added page_lock/page_unlock to uncharge_list() and it fixes my problem, but I do not know what other effects this would have. Hopefully, some of this information can help someone more knowledgable than me. Thanks. Brad Bolen -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: email@kvack.org