From patchwork Mon Jan 28 00:30:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wei Yang X-Patchwork-Id: 10783115 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 7BC216C2 for ; Mon, 28 Jan 2019 00:31:21 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6B71B2A57C for ; Mon, 28 Jan 2019 00:31:21 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 600282A580; Mon, 28 Jan 2019 00:31:21 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,MAILING_LIST_MULTI, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from ml01.01.org (ml01.01.org [198.145.21.10]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 020172A57C for ; Mon, 28 Jan 2019 00:31:21 +0000 (UTC) Received: from [127.0.0.1] (localhost [IPv6:::1]) by ml01.01.org (Postfix) with ESMTP id EB88F211BA455; Sun, 27 Jan 2019 16:31:20 -0800 (PST) X-Original-To: linux-nvdimm@lists.01.org Delivered-To: linux-nvdimm@lists.01.org Received-SPF: None (no SPF record) identity=mailfrom; client-ip=134.134.136.126; helo=mga18.intel.com; envelope-from=richardw.yang@linux.intel.com; receiver=linux-nvdimm@lists.01.org Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id D9B3F21959CB2 for ; Sun, 27 Jan 2019 16:31:19 -0800 (PST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga005.jf.intel.com ([10.7.209.41]) by orsmga106.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 27 Jan 2019 16:31:19 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.56,532,1539673200"; d="scan'208";a="294898085" Received: from richard.sh.intel.com (HELO localhost) ([10.239.159.37]) by orsmga005.jf.intel.com with ESMTP; 27 Jan 2019 16:31:18 -0800 From: Wei Yang To: linux-nvdimm@lists.01.org Subject: [PATCH 5/5] libnvdimm, namespace: allocate devs for namespace just once Date: Mon, 28 Jan 2019 08:30:18 +0800 Message-Id: <20190128003018.4087-5-richardw.yang@linux.intel.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20190128003018.4087-1-richardw.yang@linux.intel.com> References: <20190128003018.4087-1-richardw.yang@linux.intel.com> MIME-Version: 1.0 X-BeenThere: linux-nvdimm@lists.01.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "Linux-nvdimm developer list." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: zwisler@kernel.org Errors-To: linux-nvdimm-bounces@lists.01.org Sender: "Linux-nvdimm" X-Virus-Scanned: ClamAV using ClamSMTP Current scan_labels() will allocate devs for namespace step by step. The logic is correct while it requires: * more interaction with mm subsystem * memcpy for each new allocation Since each namespace has different uuid for its label, we can calculate the number of possible namespace during label initialization and allocate devs for namespace just once. This patch achieve the effect by: * add a labels_uuid_num field in nd_mapping * record number of different label uuid in labels_uuid_num * allocate devs for namespace based on labels_uuid_num After that, we could clean up the memory allocation in scan_labels(). Signed-off-by: Wei Yang --- drivers/nvdimm/namespace_devs.c | 29 +++++++++++++++++------------ drivers/nvdimm/nd.h | 1 + drivers/nvdimm/region_devs.c | 1 + 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/drivers/nvdimm/namespace_devs.c b/drivers/nvdimm/namespace_devs.c index cdf3049bd2b9..53ac2716b2b4 100644 --- a/drivers/nvdimm/namespace_devs.c +++ b/drivers/nvdimm/namespace_devs.c @@ -2293,10 +2293,14 @@ static struct device **scan_labels(struct nd_region *nd_region) struct nd_mapping *nd_mapping = &nd_region->mapping[0]; resource_size_t map_end = nd_mapping->start + nd_mapping->size - 1; + devs = kcalloc(nd_mapping->labels_uuid_num + 2, + sizeof(dev), GFP_KERNEL); + if (!devs) + return NULL; + /* "safe" because create_namespace_pmem() might list_move() label_ent */ list_for_each_entry_safe(label_ent, e, &nd_mapping->labels, list) { struct nd_namespace_label *nd_label = label_ent->label; - struct device **__devs; u32 flags; if (!nd_label) @@ -2317,12 +2321,6 @@ static struct device **scan_labels(struct nd_region *nd_region) goto err; if (i < count) continue; - __devs = kcalloc(count + 2, sizeof(dev), GFP_KERNEL); - if (!__devs) - goto err; - memcpy(__devs, devs, sizeof(dev) * count); - kfree(devs); - devs = __devs; if (is_nd_blk(&nd_region->dev)) dev = create_namespace_blk(nd_region, nd_label, count); @@ -2358,9 +2356,6 @@ static struct device **scan_labels(struct nd_region *nd_region) /* Publish a zero-sized namespace for userspace to configure. */ nd_mapping_free_labels(nd_mapping); - devs = kcalloc(2, sizeof(dev), GFP_KERNEL); - if (!devs) - goto err; if (is_nd_blk(&nd_region->dev)) { struct nd_namespace_blk *nsblk; @@ -2452,11 +2447,12 @@ static struct device **create_namespaces(struct nd_region *nd_region) static int __init_active_labels(struct nd_mapping *nd_mapping, int count) { struct nvdimm_drvdata *ndd = nd_mapping->ndd; - struct nd_label_ent *label_ent; + struct nd_label_ent *label_ent, *e; int j; for (j = 0; j < count; j++) { - struct nd_namespace_label *label; + struct nd_namespace_label *label, *l; + int new_uuid = 1; label_ent = kzalloc(sizeof(*label_ent), GFP_KERNEL); if (!label_ent) @@ -2465,6 +2461,15 @@ static int __init_active_labels(struct nd_mapping *nd_mapping, int count) label_ent->label = label; mutex_lock(&nd_mapping->lock); + list_for_each_entry(e, &nd_mapping->labels, list) { + l = e->label; + + if (!memcmp(label->uuid, l->uuid, NSLABEL_UUID_LEN)) { + new_uuid = 0; + break; + } + } + nd_mapping->labels_uuid_num += new_uuid; list_add_tail(&label_ent->list, &nd_mapping->labels); mutex_unlock(&nd_mapping->lock); } diff --git a/drivers/nvdimm/nd.h b/drivers/nvdimm/nd.h index e79cc8e5c114..b143a67a1a34 100644 --- a/drivers/nvdimm/nd.h +++ b/drivers/nvdimm/nd.h @@ -128,6 +128,7 @@ struct nd_mapping { u64 start; u64 size; int position; + int labels_uuid_num; struct list_head labels; struct mutex lock; /* diff --git a/drivers/nvdimm/region_devs.c b/drivers/nvdimm/region_devs.c index e7377f1028ef..cb10cd2045ef 100644 --- a/drivers/nvdimm/region_devs.c +++ b/drivers/nvdimm/region_devs.c @@ -1049,6 +1049,7 @@ static struct nd_region *nd_region_create(struct nvdimm_bus *nvdimm_bus, nd_region->mapping[i].size = mapping->size; nd_region->mapping[i].position = mapping->position; INIT_LIST_HEAD(&nd_region->mapping[i].labels); + nd_region->mapping[i].labels_uuid_num = 0; mutex_init(&nd_region->mapping[i].lock); get_device(&nvdimm->dev);