linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Tejun Heo <tj@kernel.org>
To: Peter Wu <lekensteyn@gmail.com>
Cc: Alan Stern <stern@rowland.harvard.edu>,
	Kernel development list <linux-kernel@vger.kernel.org>,
	Jens Axboe <axboe@kernel.dk>
Subject: Re: [PATCH] writeback: fix NULL dereference when device is gone
Date: Tue, 20 Aug 2013 09:33:08 -0400	[thread overview]
Message-ID: <20130820133308.GE3926@htj.dyndns.org> (raw)
In-Reply-To: <1755678.6GItDDY0bW@al>

Hello,

On Tue, Aug 20, 2013 at 12:13:58PM +0200, Peter Wu wrote:
...
> > Hmmm... bdi->dev is cleared after bdi_wb_shutdown() so the work item
> > should no longer be running.  It seems like something is queueing the
> > work item after shutdown and the proper fix would be finding out which
> > and fixing it.  Can you please verify whether adding
> > WARN_ON(!bdi->dev) in bdi_wakeup_thread_delayed() trigger anything?
> 
> Initially I did not get any warnings, so I added more. The patch (on top of
> v3.11-rc6-27-g94fc5d9 plus some unrelated r8169 patches):
...
> [  245.978170] WARNING: CPU: 1 PID: 2608 at /home/pc/Linux-src/linux/mm/backing-dev.c:293 bdi_wakeup_thread_delayed+0x5e/0x60()
> [  245.978189] Modules linked in: kvm_intel kvm dm_crypt binfmt_misc joydev snd_hda_codec_hdmi snd_hda_codec_realtek hid_logitech_dj hid_generic mxm_wmi nls_iso8859_1 snd_hda_intel snd_hda_codec usbhid hid snd_hwdep psmouse usb_storage snd_pcm serio_raw lpc_ich snd_seq_midi snd_seq_midi_event snd_rawmidi snd_seq snd_seq_device snd_timer snd wmi it87 mac_hid hwmon_vid coretemp soundcore snd_page_alloc r8169 eeprom_93cx6 mii pci_stub ahci libahci i915 drm_kms_helper drm video i2c_algo_bit
> [  245.978191] CPU: 1 PID: 2608 Comm: ata_id Tainted: G        W    3.11.0-rc6-usbdbg-00030-g693d742-dirty #1
> [  245.978192] Hardware name: Gigabyte Technology Co., Ltd. To be filled by O.E.M./Z68X-UD3H-B3, BIOS U1l 03/08/2013
> [  245.978194]  0000000000000125 ffff8805d3a4fa98 ffffffff8165986e 00000000000060d0
> [  245.978196]  0000000000000000 ffff8805d3a4fad8 ffffffff81047acc ffff880602f6beb8
> [  245.978197]  ffff8805fc024618 ffff880602f6be30 ffffffff81c58f80 ffff880602f6beb8
> [  245.978198] Call Trace:
> [  245.978202]  [<ffffffff8165986e>] dump_stack+0x55/0x76
> [  245.978204]  [<ffffffff81047acc>] warn_slowpath_common+0x8c/0xc0
> [  245.978206]  [<ffffffff81047b1a>] warn_slowpath_null+0x1a/0x20
> [  245.978207]  [<ffffffff811424fe>] bdi_wakeup_thread_delayed+0x5e/0x60
> [  245.978211]  [<ffffffff811bdc71>] bdev_inode_switch_bdi+0xf1/0x160
> [  245.978212]  [<ffffffff811bedd2>] __blkdev_get+0x372/0x4d0
> [  245.978216]  [<ffffffff811bf115>] blkdev_get+0x1e5/0x380
> [  245.978221]  [<ffffffff811bf36f>] blkdev_open+0x5f/0x90
> [  245.978223]  [<ffffffff81180cd6>] do_dentry_open+0x226/0x2a0
> [  245.978225]  [<ffffffff81180fa5>] finish_open+0x35/0x50
> [  245.978227]  [<ffffffff81192d9e>] do_last+0x48e/0x7a0
> [  245.978229]  [<ffffffff81193174>] path_openat+0xc4/0x4e0
> [  245.978230]  [<ffffffff81193d83>] do_filp_open+0x43/0xa0
> [  245.978234]  [<ffffffff81182422>] do_sys_open+0x132/0x220
> [  245.978236]  [<ffffffff8118252e>] SyS_open+0x1e/0x20
> [  245.978238]  [<ffffffff8166e802>] system_call_fastpath+0x16/0x1b

Hmmm... looks like the udev event handling from hotunplugging ends up
opening up the device which in turn schedules an already shutdown bdi.
The root problem here seems that there is no proper synchronization
around bdi shutdown.  Ideally, a bdi should be marked offline
preventing further activities and then shut down but we instead shut
it down first and then clear bdi->dev.  As bdi's lifetime is tied to
the backing request_queue, it might be okay as unsynchronized access
to bdi->dev should be safe as long as the bdi struct itself is
accessible.  Still nasty tho.

Not sure what to do.  The quick fix would be doing the following from
workfn().

	dev = bdi->dev;
	if (!dev)		// bdi already shutdown
		return;

	use @dev;		// can't use bdi->dev, as it can be cleared anytime

But it's nasty.  A better way to do it would be, from
bdi_wb_shutdown(), marking the bdi as offline and ensure that
bdi_wakeup_thread_delayed() sees that, flush the work item and then
clear bdi->dev.

Thanks.

-- 
tejun

  reply	other threads:[~2013-08-20 13:33 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-08-18  1:08 [3.11-rc5..] NULL pointer dereference in bdi_writeback_workfn Alan Stern
2013-08-19 22:45 ` [PATCH] writeback: fix NULL dereference when device is gone Peter Wu
2013-08-19 23:02   ` Tejun Heo
2013-08-20 10:13     ` Peter Wu
2013-08-20 13:33       ` Tejun Heo [this message]
2013-08-28 22:31         ` Peter Wu
2013-09-04 18:21           ` Tejun Heo

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20130820133308.GE3926@htj.dyndns.org \
    --to=tj@kernel.org \
    --cc=axboe@kernel.dk \
    --cc=lekensteyn@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=stern@rowland.harvard.edu \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).