From patchwork Fri Nov 22 20:07:08 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mikulas Patocka X-Patchwork-Id: 3224151 Return-Path: X-Original-To: patchwork-dm-devel@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 62E669F26C for ; Fri, 22 Nov 2013 20:10:50 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 6716C207B4 for ; Fri, 22 Nov 2013 20:10:49 +0000 (UTC) Received: from mx3-phx2.redhat.com (mx3-phx2.redhat.com [209.132.183.24]) by mail.kernel.org (Postfix) with ESMTP id 1D6542076C for ; Fri, 22 Nov 2013 20:10:48 +0000 (UTC) Received: from lists01.pubmisc.prod.ext.phx2.redhat.com (lists01.pubmisc.prod.ext.phx2.redhat.com [10.5.19.33]) by mx3-phx2.redhat.com (8.13.8/8.13.8) with ESMTP id rAMK79W8002134; Fri, 22 Nov 2013 15:07:10 -0500 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) by lists01.pubmisc.prod.ext.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id rAMK795R005879 for ; Fri, 22 Nov 2013 15:07:09 -0500 Received: from file01.intranet.prod.int.rdu2.redhat.com (file01.intranet.prod.int.rdu2.redhat.com [10.11.5.7]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id rAMK78MF027049 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Fri, 22 Nov 2013 15:07:08 -0500 Received: from file01.intranet.prod.int.rdu2.redhat.com (localhost [127.0.0.1]) by file01.intranet.prod.int.rdu2.redhat.com (8.14.4/8.14.4) with ESMTP id rAMK78NW028979; Fri, 22 Nov 2013 15:07:08 -0500 Received: from localhost (mpatocka@localhost) by file01.intranet.prod.int.rdu2.redhat.com (8.14.4/8.14.4/Submit) with ESMTP id rAMK782i028975; Fri, 22 Nov 2013 15:07:08 -0500 X-Authentication-Warning: file01.intranet.prod.int.rdu2.redhat.com: mpatocka owned process doing -bs Date: Fri, 22 Nov 2013 15:07:08 -0500 (EST) From: Mikulas Patocka X-X-Sender: mpatocka@file01.intranet.prod.int.rdu2.redhat.com To: Neil Brown , linux-raid@vger.kernel.org, Shaohua Li Message-ID: User-Agent: Alpine 2.02 (LRH 1266 2009-07-14) MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-loop: dm-devel@redhat.com Cc: dm-devel@redhat.com, Zdenek Kabelac Subject: [dm-devel] [PATCH] Revert "raid5: make release_stripe lockless" because it causes test regression X-BeenThere: dm-devel@redhat.com X-Mailman-Version: 2.1.12 Precedence: junk Reply-To: device-mapper development List-Id: device-mapper development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: dm-devel-bounces@redhat.com Errors-To: dm-devel-bounces@redhat.com X-Spam-Status: No, score=-7.4 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Revert 773ca82fa1ee58dd1bf88b6a5ca385ec83a2cac6 and d265d9dc1d25a69affc21ae9fe5004b9d09c10ef. The lvm testsuite (from ftp://sources.redhat.com/pub/lvm2/LVM2.2.02.104.tgz) fails with unkillable lvm and dmsetup processes on kernel 3.12. The testsuite passes on 3.11. Bisect shows that the failure is caused by patch 773ca82fa1ee58dd1bf88b6a5ca385ec83a2cac6. When I revert this patch on 3.12 kernel, the testsuite finishes and there are no unkillable processes. Signed-off-by: Mikulas Patocka Cc: stable@kernel.org # 3.12 --- drivers/md/raid5.c | 70 +++-------------------------------------------------- drivers/md/raid5.h | 3 -- 2 files changed, 5 insertions(+), 68 deletions(-) -- dm-devel mailing list dm-devel@redhat.com https://www.redhat.com/mailman/listinfo/dm-devel Index: linux-3.12-fast/drivers/md/raid5.c =================================================================== --- linux-3.12-fast.orig/drivers/md/raid5.c 2013-11-21 22:45:20.000000000 +0100 +++ linux-3.12-fast/drivers/md/raid5.c 2013-11-21 23:39:01.000000000 +0100 @@ -293,62 +293,12 @@ static void __release_stripe(struct r5co do_release_stripe(conf, sh); } -static struct llist_node *llist_reverse_order(struct llist_node *head) -{ - struct llist_node *new_head = NULL; - - while (head) { - struct llist_node *tmp = head; - head = head->next; - tmp->next = new_head; - new_head = tmp; - } - - return new_head; -} - -/* should hold conf->device_lock already */ -static int release_stripe_list(struct r5conf *conf) -{ - struct stripe_head *sh; - int count = 0; - struct llist_node *head; - - head = llist_del_all(&conf->released_stripes); - head = llist_reverse_order(head); - while (head) { - sh = llist_entry(head, struct stripe_head, release_list); - head = llist_next(head); - /* sh could be readded after STRIPE_ON_RELEASE_LIST is cleard */ - smp_mb(); - clear_bit(STRIPE_ON_RELEASE_LIST, &sh->state); - /* - * Don't worry the bit is set here, because if the bit is set - * again, the count is always > 1. This is true for - * STRIPE_ON_UNPLUG_LIST bit too. - */ - __release_stripe(conf, sh); - count++; - } - - return count; -} - static void release_stripe(struct stripe_head *sh) { struct r5conf *conf = sh->raid_conf; unsigned long flags; - bool wakeup; - if (test_and_set_bit(STRIPE_ON_RELEASE_LIST, &sh->state)) - goto slow_path; - wakeup = llist_add(&sh->release_list, &conf->released_stripes); - if (wakeup) - md_wakeup_thread(conf->mddev->thread); - return; -slow_path: local_irq_save(flags); - /* we are ok here if STRIPE_ON_RELEASE_LIST is set or not */ if (atomic_dec_and_lock(&sh->count, &conf->device_lock)) { do_release_stripe(conf, sh); spin_unlock(&conf->device_lock); @@ -596,8 +546,7 @@ get_active_stripe(struct r5conf *conf, s if (atomic_read(&sh->count)) { BUG_ON(!list_empty(&sh->lru) && !test_bit(STRIPE_EXPANDING, &sh->state) - && !test_bit(STRIPE_ON_UNPLUG_LIST, &sh->state) - && !test_bit(STRIPE_ON_RELEASE_LIST, &sh->state)); + && !test_bit(STRIPE_ON_UNPLUG_LIST, &sh->state)); } else { if (!test_bit(STRIPE_HANDLE, &sh->state)) atomic_inc(&conf->active_stripes); @@ -4293,10 +4242,6 @@ static void raid5_unplug(struct blk_plug */ smp_mb__before_clear_bit(); clear_bit(STRIPE_ON_UNPLUG_LIST, &sh->state); - /* - * STRIPE_ON_RELEASE_LIST could be set here. In that - * case, the count is always > 1 here - */ __release_stripe(conf, sh); cnt++; } @@ -5007,13 +4952,11 @@ static void raid5_do_work(struct work_st handled = 0; spin_lock_irq(&conf->device_lock); while (1) { - int batch_size, released; - - released = release_stripe_list(conf); + int batch_size; batch_size = handle_active_stripes(conf, group_id, worker); worker->working = false; - if (!batch_size && !released) + if (!batch_size) break; handled += batch_size; } @@ -5048,9 +4991,7 @@ static void raid5d(struct md_thread *thr spin_lock_irq(&conf->device_lock); while (1) { struct bio *bio; - int batch_size, released; - - released = release_stripe_list(conf); + int batch_size; if ( !list_empty(&conf->bitmap_list)) { @@ -5075,7 +5016,7 @@ static void raid5d(struct md_thread *thr } batch_size = handle_active_stripes(conf, ANY_GROUP, NULL); - if (!batch_size && !released) + if (!batch_size) break; handled += batch_size; @@ -5503,7 +5444,6 @@ static struct r5conf *setup_conf(struct INIT_LIST_HEAD(&conf->delayed_list); INIT_LIST_HEAD(&conf->bitmap_list); INIT_LIST_HEAD(&conf->inactive_list); - init_llist_head(&conf->released_stripes); atomic_set(&conf->active_stripes, 0); atomic_set(&conf->preread_active_stripes, 0); atomic_set(&conf->active_aligned_reads, 0); Index: linux-3.12-fast/drivers/md/raid5.h =================================================================== --- linux-3.12-fast.orig/drivers/md/raid5.h 2013-11-21 23:29:32.000000000 +0100 +++ linux-3.12-fast/drivers/md/raid5.h 2013-11-21 23:29:35.000000000 +0100 @@ -197,7 +197,6 @@ enum reconstruct_states { struct stripe_head { struct hlist_node hash; struct list_head lru; /* inactive_list or handle_list */ - struct llist_node release_list; struct r5conf *raid_conf; short generation; /* increments with every * reshape */ @@ -324,7 +323,6 @@ enum { STRIPE_OPS_REQ_PENDING, STRIPE_ON_UNPLUG_LIST, STRIPE_DISCARD, - STRIPE_ON_RELEASE_LIST, }; /* @@ -463,7 +461,6 @@ struct r5conf { */ atomic_t active_stripes; struct list_head inactive_list; - struct llist_head released_stripes; wait_queue_head_t wait_for_stripe; wait_queue_head_t wait_for_overlap; int inactive_blocked; /* release of inactive stripes blocked,