From patchwork Wed Dec 2 12:16:23 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Matias_Bj=C3=B8rling?= X-Patchwork-Id: 7745541 Return-Path: X-Original-To: patchwork-linux-block@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 4F24C9F350 for ; Wed, 2 Dec 2015 12:17:33 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 5679C20631 for ; Wed, 2 Dec 2015 12:17:32 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 5897E205B7 for ; Wed, 2 Dec 2015 12:17:31 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756393AbbLBMRN (ORCPT ); Wed, 2 Dec 2015 07:17:13 -0500 Received: from mail-wm0-f47.google.com ([74.125.82.47]:35599 "EHLO mail-wm0-f47.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754368AbbLBMQz (ORCPT ); Wed, 2 Dec 2015 07:16:55 -0500 Received: by wmuu63 with SMTP id u63so212226663wmu.0 for ; Wed, 02 Dec 2015 04:16:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bjorling.me; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-type:content-transfer-encoding; bh=fN+Hp8SyOJjYHh5N/cGeg/mO1OdA+qAjEQvksIpOFMA=; b=sdgxB5aFRsNv0KXvnbfICSWaTy1pYd08N5XdkwhJ4mTToyjn0HTg3cghscpF98o520 f9lC4p35PG+fmj5TwdVADYSDGsdk0+IethZKHkMaX+E9T1e1GzPh/oiGiR83q76mKbUS a7YLsxFC7gSA/W+aqQh849gA69yTuF3Fma+GY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-type:content-transfer-encoding; bh=fN+Hp8SyOJjYHh5N/cGeg/mO1OdA+qAjEQvksIpOFMA=; b=I7lDAcWOeHcxt87KuLf9eMg+O+W+vPCJiUPIFBs3ZvLMJsZRPcMBuN6dLbp23kgw5d v9EUltf3sPWxVyA8+FoFjC8RprDxpmrWc/duixdc3oLEzYXs10XQxylyErXWseVbpVj2 epuiqu7gCSTt4X7ye9Y9bIFgSpWpEFxTM3sk/oysuF1d9XKiQMVU/rVOmkmF9R+jKWTJ rPHHBgI2pS6ViGUS4Ts8Jt4ZDy+mCqQfzqXsVzlU6jaJoU69erGmSp5gu+yuA5J2v6Q8 udjIWc8Q3aCl44TU8Gt4APIi/veZrnNocOQ7f8JjklEYqmr0djbm2fXogK1DarDiPquk Qwmw== X-Gm-Message-State: ALoCoQkYma15UF3B0EAjnEaWZ8O0vBXtjkESuYcTylRPkA3/B/fHqR0MeWzr1Tq6JdccS4Mt2Ykt X-Received: by 10.194.20.164 with SMTP id o4mr4358307wje.105.1449058613948; Wed, 02 Dec 2015 04:16:53 -0800 (PST) Received: from localhost.localdomain (6164198-cl69.boa.fiberby.dk. [193.106.164.198]) by smtp.gmail.com with ESMTPSA id q9sm2556213wjo.9.2015.12.02.04.16.53 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 02 Dec 2015 04:16:53 -0800 (PST) From: =?UTF-8?q?Matias=20Bj=C3=B8rling?= To: linux-block@vger.kernel.org, linux-kernel@vger.kernel.org Cc: =?UTF-8?q?Matias=20Bj=C3=B8rling?= Subject: [PATCH RFC 3/3] lightnvm: fix media mgr registration Date: Wed, 2 Dec 2015 13:16:23 +0100 Message-Id: <1449058583-27940-3-git-send-email-m@bjorling.me> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1449058583-27940-1-git-send-email-m@bjorling.me> References: <1449058583-27940-1-git-send-email-m@bjorling.me> MIME-Version: 1.0 Sender: linux-block-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org X-Spam-Status: No, score=-6.8 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID,T_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 The ppa pool can be used at media manager registration. Therefore the ppa pool should be allocated before registering. If a media manager can't be found, this should not lead to the device being unallocated. A media manager can be registered later, that can manage a device. Only warn if a media manager fails initialization. Additionally, protect against the media managed being registered or deregistered while looping through available media managers. This was reported by Wenwei Tao. Signed-off-by: Matias Bjørling --- drivers/lightnvm/core.c | 79 ++++++++++++++++++++++++------------------------- 1 file changed, 39 insertions(+), 40 deletions(-) diff --git a/drivers/lightnvm/core.c b/drivers/lightnvm/core.c index 4601cf1..f4d5291 100644 --- a/drivers/lightnvm/core.c +++ b/drivers/lightnvm/core.c @@ -97,15 +97,47 @@ static struct nvmm_type *nvm_find_mgr_type(const char *name) return NULL; } +struct nvmm_type *nvm_init_mgr(struct nvm_dev *dev) +{ + struct nvmm_type *mt; + int ret; + + lockdep_assert_held(&nvm_lock); + + list_for_each_entry(mt, &nvm_mgrs, list) { + ret = mt->register_mgr(dev); + if (ret < 0) { + pr_err("nvm: media mgr failed to init (%d) on dev %s\n", + ret, dev->name); + return NULL; /* initialization failed */ + } else if (ret > 0) + return mt; + } + + return NULL; +} + int nvm_register_mgr(struct nvmm_type *mt) { + struct nvm_dev *dev; int ret = 0; down_write(&nvm_lock); - if (nvm_find_mgr_type(mt->name)) + if (nvm_find_mgr_type(mt->name)) { ret = -EEXIST; - else + goto finish; + } else { list_add(&mt->list, &nvm_mgrs); + } + + /* try to register media mgr if any device have none configured */ + list_for_each_entry(dev, &nvm_devices, devices) { + if (dev->mt) + continue; + + dev->mt = nvm_init_mgr(dev); + } +finish: up_write(&nvm_lock); return ret; @@ -221,7 +253,6 @@ static void nvm_free(struct nvm_dev *dev) static int nvm_init(struct nvm_dev *dev) { - struct nvmm_type *mt; int ret = -EINVAL; if (!dev->q || !dev->ops) @@ -252,22 +283,6 @@ static int nvm_init(struct nvm_dev *dev) goto err; } - /* register with device with a supported manager */ - list_for_each_entry(mt, &nvm_mgrs, list) { - ret = mt->register_mgr(dev); - if (ret < 0) - goto err; /* initialization failed */ - if (ret > 0) { - dev->mt = mt; - break; /* successfully initialized */ - } - } - - if (!ret) { - pr_info("nvm: no compatible manager found.\n"); - return 0; - } - pr_info("nvm: registered %s [%u/%u/%u/%u/%u/%u]\n", dev->name, dev->sec_per_pg, dev->nr_planes, dev->pgs_per_blk, dev->blks_per_lun, dev->nr_luns, @@ -324,7 +339,9 @@ int nvm_register(struct request_queue *q, char *disk_name, } } + /* register device with a supported media manager */ down_write(&nvm_lock); + dev->mt = nvm_init_mgr(dev); list_add(&dev->devices, &nvm_devices); up_write(&nvm_lock); @@ -365,35 +382,17 @@ static int nvm_create_target(struct nvm_dev *dev, { struct nvm_ioctl_create_simple *s = &create->conf.s; struct request_queue *tqueue; - struct nvmm_type *mt; struct gendisk *tdisk; struct nvm_tgt_type *tt; struct nvm_target *t; void *targetdata; - int ret = 0; - down_write(&nvm_lock); if (!dev->mt) { - /* register with device with a supported NVM manager */ - list_for_each_entry(mt, &nvm_mgrs, list) { - ret = mt->register_mgr(dev); - if (ret < 0) { - up_write(&nvm_lock); - return ret; /* initialization failed */ - } - if (ret > 0) { - dev->mt = mt; - break; /* successfully initialized */ - } - } - - if (!ret) { - up_write(&nvm_lock); - pr_info("nvm: no compatible nvm manager found.\n"); - return -ENODEV; - } + pr_info("nvm: device has no media manager registered.\n"); + return -ENODEV; } + down_write(&nvm_lock); tt = nvm_find_target_type(create->tgttype); if (!tt) { pr_err("nvm: target type %s not found\n", create->tgttype);