From patchwork Thu Sep 25 13:53:24 2008 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexander Belyakov X-Patchwork-Id: 1526 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from bombadil.infradead.org (bombadil.infradead.org [18.85.46.34]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 4610EDE031 for ; Fri, 26 Sep 2008 00:00:28 +1000 (EST) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.68 #1 (Red Hat Linux)) id 1KirHo-0002gu-8U; Thu, 25 Sep 2008 13:53:40 +0000 Received: from f144.mail.ru ([194.67.57.137]) by bombadil.infradead.org with esmtp (Exim 4.68 #1 (Red Hat Linux)) id 1KirHa-0002gj-J4 for linux-mtd@lists.infradead.org; Thu, 25 Sep 2008 13:53:26 +0000 Received: from mail by f144.mail.ru with local id 1KirHY-0009gF-00; Thu, 25 Sep 2008 17:53:24 +0400 Received: from [192.55.37.193] by win.mail.ru with HTTP; Thu, 25 Sep 2008 17:53:24 +0400 From: Alexander Belyakov To: David Woodhouse , Nicolas Pitre , =?windows-1251?Q?linux-mtd=40lists.infradead.org?= Subject: =?windows-1251?Q?[PATCH]_mtd=3A_fix_cfi=5Fcmdset=5F0001_FL=5FSYNCING_race_(take_2)?= Mime-Version: 1.0 X-Mailer: mPOP Web-Mail 2.19 X-Originating-IP: unknown via proxy [192.55.37.193] Date: Thu, 25 Sep 2008 17:53:24 +0400 Message-Id: X-Spam: Not detected X-Mras: OK X-Spam-Score: 0.0 (/) Cc: Alexander Belyakov X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.9 Precedence: list Reply-To: Alexander Belyakov List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: linux-mtd-bounces@lists.infradead.org Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org The patch fixes CFI issue with multipartitional devices leading to the set of errors or even deadlock. The problem is CFI FL_SYNCING state race with flash operations (e.g. erase suspend). It is reproduced by running intensive writes on one JFFS2 partition and simultaneously performing mount/unmount cycle on another partition of the same chip. Acked-by: Nicolas Pitre otherwise. --- Signed-off-by: Alexander Belyakov diff -uNrp a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c --- a/drivers/mtd/chips/cfi_cmdset_0001.c 2008-09-08 21:40:20.000000000 +0400 +++ b/drivers/mtd/chips/cfi_cmdset_0001.c 2008-09-19 10:47:34.000000000 +0400 @@ -701,6 +701,10 @@ static int chip_ready (struct map_info * struct cfi_pri_intelext *cfip = cfi->cmdset_priv; unsigned long timeo = jiffies + HZ; + /* Prevent setting state FL_SYNCING for chip in suspended state. */ + if (mode == FL_SYNCING && chip->oldstate != FL_READY) + goto sleep; + switch (chip->state) { case FL_STATUS: @@ -806,8 +810,9 @@ static int get_chip(struct map_info *map DECLARE_WAITQUEUE(wait, current); retry: - if (chip->priv && (mode == FL_WRITING || mode == FL_ERASING - || mode == FL_OTP_WRITE || mode == FL_SHUTDOWN)) { + if (chip->priv && + (mode == FL_WRITING || mode == FL_ERASING || mode == FL_OTP_WRITE + || mode == FL_SHUTDOWN) && chip->state != FL_SYNCING) { /* * OK. We have possibility for contention on the write/erase * operations which are global to the real chip and not per @@ -857,6 +862,14 @@ static int get_chip(struct map_info *map return ret; } spin_lock(&shared->lock); + + /* We should not own chip if it is already + * in FL_SYNCING state. Put contender and retry. */ + if (chip->state == FL_SYNCING) { + put_chip(map, contender, contender->start); + spin_unlock(contender->mutex); + goto retry; + } spin_unlock(contender->mutex); }