From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932206Ab0EYBSx (ORCPT ); Mon, 24 May 2010 21:18:53 -0400 Received: from mga09.intel.com ([134.134.136.24]:3175 "EHLO mga09.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1758306Ab0EYBSv (ORCPT ); Mon, 24 May 2010 21:18:51 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="4.53,295,1272870000"; d="scan'208";a="624469945" Date: Tue, 25 May 2010 09:18:49 +0800 From: Shaohua Li To: linux-kernel@vger.kernel.org Cc: jens.axboe@oracle.com, jmoyer@redhat.com Subject: [PATCH]cfq-iosched: fix an oops caused by slab leak Message-ID: <20100525011849.GA29820@sli10-desk.sh.intel.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.5.20 (2009-06-14) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org I got below oops when unloading cfq-iosched. Considering scenario: queue A merge to B, C merge to D and B will be merged to D. Before B is merged to D, we do split B. We should put B's reference for D. [ 807.768536] ============================================================================= [ 807.768539] BUG cfq_queue: Objects remaining on kmem_cache_close() [ 807.768541] ----------------------------------------------------------------------------- [ 807.768543] [ 807.768546] INFO: Slab 0xffffea0003e6b4e0 objects=26 used=1 fp=0xffff88011d584fd8 flags=0x200000000004082 [ 807.768550] Pid: 5946, comm: rmmod Tainted: G W 2.6.34-07097-gf4b87de-dirty #724 [ 807.768552] Call Trace: [ 807.768560] [] slab_err+0x8f/0x9d [ 807.768564] [] ? flush_cpu_slab+0x0/0x93 [ 807.768569] [] ? add_preempt_count+0xe/0xca [ 807.768572] [] ? sub_preempt_count+0xe/0xb6 [ 807.768577] [] ? _raw_spin_unlock+0x15/0x30 [ 807.768580] [] ? sub_preempt_count+0xe/0xb6 [ 807.768584] [] list_slab_objects+0x9b/0x19f [ 807.768588] [] ? add_preempt_count+0xc6/0xca [ 807.768591] [] kmem_cache_destroy+0x13f/0x21d [ 807.768597] [] cfq_slab_kill+0x1a/0x43 [cfq_iosched] [ 807.768601] [] cfq_exit+0x93/0x9e [cfq_iosched] [ 807.768606] [] sys_delete_module+0x1b1/0x219 [ 807.768612] [] system_call_fastpath+0x16/0x1b [ 807.768618] INFO: Object 0xffff88011d584618 @offset=1560 [ 807.768622] INFO: Allocated in cfq_get_queue+0x11e/0x274 [cfq_iosched] age=7173 cpu=1 pid=5496 [ 807.768626] ============================================================================= Signed-off-by: Shaohua Li diff --git a/block/cfq-iosched.c b/block/cfq-iosched.c index ed897b5..855fd5f 100644 --- a/block/cfq-iosched.c +++ b/block/cfq-iosched.c @@ -2537,15 +2537,10 @@ static void cfq_free_io_context(struct io_context *ioc) __call_for_each_cic(ioc, cic_free_func); } -static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq) +static void cfq_put_cooperator(struct cfq_queue *cfqq) { struct cfq_queue *__cfqq, *next; - if (unlikely(cfqq == cfqd->active_queue)) { - __cfq_slice_expired(cfqd, cfqq, 0); - cfq_schedule_dispatch(cfqd); - } - /* * If this queue was scheduled to merge with another queue, be * sure to drop the reference taken on that queue (and others in @@ -2561,6 +2556,16 @@ static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq) cfq_put_queue(__cfqq); __cfqq = next; } +} + +static void cfq_exit_cfqq(struct cfq_data *cfqd, struct cfq_queue *cfqq) +{ + if (unlikely(cfqq == cfqd->active_queue)) { + __cfq_slice_expired(cfqd, cfqq, 0); + cfq_schedule_dispatch(cfqd); + } + + cfq_put_cooperator(cfqq); cfq_put_queue(cfqq); } @@ -3516,6 +3521,9 @@ split_cfqq(struct cfq_io_context *cic, struct cfq_queue *cfqq) } cic_set_cfqq(cic, NULL, 1); + + cfq_put_cooperator(cfqq); + cfq_put_queue(cfqq); return NULL; }