From patchwork Sat Mar 19 16:58:57 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Wenwei Tao X-Patchwork-Id: 8625521 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 6928E9F54C for ; Sat, 19 Mar 2016 17:00:42 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 34006203EB for ; Sat, 19 Mar 2016 17:00:41 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 84DE7203FB for ; Sat, 19 Mar 2016 17:00:39 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754999AbcCSRAc (ORCPT ); Sat, 19 Mar 2016 13:00:32 -0400 Received: from mail-pf0-f194.google.com ([209.85.192.194]:35395 "EHLO mail-pf0-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754941AbcCSRAZ (ORCPT ); Sat, 19 Mar 2016 13:00:25 -0400 Received: by mail-pf0-f194.google.com with SMTP id u190so22316905pfb.2; Sat, 19 Mar 2016 10:00:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Q2eO42YGKvmKr5WVKDqM8W5LP+wT0UA+z54sTwTdBtc=; b=Tb7kT9F+94JvQL9QjWV3icgQXYOru+GN1VD2HgSwF10IayL43aX3Onn/C/n5cpSHM6 k2JzGfAWcRZU4yb9PpZilqLXWCtnOYMcBWDS0LPMRTHAxyKSK4auiMcDwb4phAlVyGSq GOwWRPIw0qiXYtTsdgNy6V9NtAtpZrF8m5QVizUS9B/i+AkVhJSfiTDY3i/TkkmH5LX1 zYJC/FYeGYckpko+bLzDJbmab1JtX7Sj8QYT3ldpE+J0jxFY354e/hs61JnDmI4dUcLv 6T3m0HQfsFhMRHsxgvE9ANekM7k2bqszkkAoK5kZ8ltI1YHOEcONUh1t1Sboc7TkNSnq W0QQ== 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; bh=Q2eO42YGKvmKr5WVKDqM8W5LP+wT0UA+z54sTwTdBtc=; b=SqRkM9KhsljOdLGXPLle1a8cIw+5ZDqOc2fe45j56y52nwdbS06a67/nNBDcJZjQwo vAN9WVt02GrK5IbGhACf3zEDphXA/cBOBiC5piB2odKsdE3lX+ZcHbKJHMzhe/qGG0Le AnU4EY4wuFeGYgW9g1ytwOf+2Vm6nQOdmx+R81bPK528d140R6G/19galEiysvYOUYWl eHq/fH9mX2ctehaCHGR2GQq98b2Z8jW5lAgFa4HzRqVvWSEcjh4bi46sQcrNYXuyOfJT X59piyazOFWOMSdX+zHcn03RctjkYYEIdg92tN7O3vtrep+DqWVpHQJSwpyp8KCoqVqj QjQw== X-Gm-Message-State: AD7BkJJ5R7+GDGbJQXtv/nasyB1ZaYd1IqdCfc4EVKI3ps77DJVIkCoWoJUOwaPmN2Nbgg== X-Received: by 10.98.32.136 with SMTP id m8mr32773213pfj.11.1458406824321; Sat, 19 Mar 2016 10:00:24 -0700 (PDT) Received: from localhost.localdomain ([2002:72f6:a61b::72f6:a61b]) by smtp.gmail.com with ESMTPSA id v14sm29268489pas.10.2016.03.19.10.00.19 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 19 Mar 2016 10:00:23 -0700 (PDT) From: Wenwei Tao To: mb@lightnvm.io, jg@lightnvm.io Cc: linux-kernel@vger.kernel.org, linux-block@vger.kernel.org Subject: [PATCH v5 2/3] lightnvm: add non-continuous lun target creation support Date: Sun, 20 Mar 2016 00:58:57 +0800 Message-Id: <1458406738-4828-2-git-send-email-ww.tao0320@gmail.com> X-Mailer: git-send-email 2.7.0.windows.2 In-Reply-To: <1458406738-4828-1-git-send-email-ww.tao0320@gmail.com> References: <1458406738-4828-1-git-send-email-ww.tao0320@gmail.com> 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_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=ham 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 When create a target, we specify the begin lunid and the end lunid, and get the corresponding continuous luns from media manager, if one of the luns is not free, we failed to create the target, even if the device's total free luns are enough. So add non-continuous lun target creation support, thus we can improve the backend device's space utilization. Signed-off-by: Wenwei Tao --- Changes since v4 -fix target creation fail. -move code concerning the per-lun reverse translation map to a new patch. Changes since v3 -limit list luns to 768, thus we don't go above a single memory page. -move NVM_DEV_FREE_LUNS to its own patch and rename it to NVM_DEV_LUNS_STATUS. -insert and delete some lines to increase readability. -rebase to for-4.6 Changes since v2 -rebase on for-next branch -move luns bitmap to PATCH 2 -remove the logic to dynamically select another lun than the one requested -implment lunid list in the lnvm ioctl interface Changes since v1 -use NVM_FIXED instead NVM_C_FIXED in gennvm_get_lun -add target creation flags check -rebase to v4.5-rc1 drivers/lightnvm/core.c | 64 ++++++++++++++++++++++++------------------- drivers/lightnvm/rrpc.c | 31 +++++++++++++++++---- include/linux/lightnvm.h | 3 +- include/uapi/linux/lightnvm.h | 9 ++++++ 4 files changed, 73 insertions(+), 34 deletions(-) diff --git a/drivers/lightnvm/core.c b/drivers/lightnvm/core.c index 0dc9a80..84bc72d 100644 --- a/drivers/lightnvm/core.c +++ b/drivers/lightnvm/core.c @@ -625,7 +625,7 @@ static const struct block_device_operations nvm_fops = { static int nvm_create_target(struct nvm_dev *dev, struct nvm_ioctl_create *create) { - struct nvm_ioctl_create_simple *s = &create->conf.s; + struct nvm_ioctl_create_conf *conf = &create->conf; struct request_queue *tqueue; struct gendisk *tdisk; struct nvm_tgt_type *tt; @@ -674,7 +674,7 @@ static int nvm_create_target(struct nvm_dev *dev, tdisk->fops = &nvm_fops; tdisk->queue = tqueue; - targetdata = tt->init(dev, tdisk, s->lun_begin, s->lun_end); + targetdata = tt->init(dev, tdisk, conf); if (IS_ERR(targetdata)) goto err_init; @@ -726,7 +726,6 @@ static void nvm_remove_target(struct nvm_target *t) static int __nvm_configure_create(struct nvm_ioctl_create *create) { struct nvm_dev *dev; - struct nvm_ioctl_create_simple *s; down_write(&nvm_lock); dev = nvm_find_nvm_dev(create->dev); @@ -736,17 +735,11 @@ static int __nvm_configure_create(struct nvm_ioctl_create *create) return -EINVAL; } - if (create->conf.type != NVM_CONFIG_TYPE_SIMPLE) { + if (create->conf.type != NVM_CONFIG_TYPE_SIMPLE && + create->conf.type != NVM_CONFIG_TYPE_LIST) { pr_err("nvm: config type not valid\n"); return -EINVAL; } - s = &create->conf.s; - - if (s->lun_begin > s->lun_end || s->lun_end > dev->nr_luns) { - pr_err("nvm: lun out of bound (%u:%u > %u)\n", - s->lun_begin, s->lun_end, dev->nr_luns); - return -EINVAL; - } return nvm_create_target(dev, create); } @@ -824,24 +817,29 @@ static int nvm_configure_remove(const char *val) static int nvm_configure_create(const char *val) { - struct nvm_ioctl_create create; + struct nvm_ioctl_create *create; char opcode; int lun_begin, lun_end, ret; - ret = sscanf(val, "%c %256s %256s %48s %u:%u", &opcode, create.dev, - create.tgtname, create.tgttype, + create = kzalloc(sizeof(struct nvm_ioctl_create), GFP_KERNEL); + if (!create) + return -ENOMEM; + + ret = sscanf(val, "%c %256s %256s %48s %u:%u", &opcode, create->dev, + create->tgtname, create->tgttype, &lun_begin, &lun_end); if (ret != 6) { pr_err("nvm: invalid command. Use \"opcode device name tgttype lun_begin:lun_end\".\n"); + kfree(create); return -EINVAL; } - create.flags = 0; - create.conf.type = NVM_CONFIG_TYPE_SIMPLE; - create.conf.s.lun_begin = lun_begin; - create.conf.s.lun_end = lun_end; + create->flags = 0; + create->conf.type = NVM_CONFIG_TYPE_SIMPLE; + create->conf.s.lun_begin = lun_begin; + create->conf.s.lun_end = lun_end; - return __nvm_configure_create(&create); + return __nvm_configure_create(create); } @@ -993,24 +991,34 @@ static long nvm_ioctl_get_devices(struct file *file, void __user *arg) static long nvm_ioctl_dev_create(struct file *file, void __user *arg) { - struct nvm_ioctl_create create; + struct nvm_ioctl_create *create; + long ret = -EINVAL; if (!capable(CAP_SYS_ADMIN)) return -EPERM; + create = kzalloc(sizeof(struct nvm_ioctl_create), GFP_KERNEL); + if (!create) + return -ENOMEM; - if (copy_from_user(&create, arg, sizeof(struct nvm_ioctl_create))) - return -EFAULT; + if (copy_from_user(create, arg, sizeof(struct nvm_ioctl_create))) { + ret = -EFAULT; + goto out; + } - create.dev[DISK_NAME_LEN - 1] = '\0'; - create.tgttype[NVM_TTYPE_NAME_MAX - 1] = '\0'; - create.tgtname[DISK_NAME_LEN - 1] = '\0'; + create->dev[DISK_NAME_LEN - 1] = '\0'; + create->tgttype[NVM_TTYPE_NAME_MAX - 1] = '\0'; + create->tgtname[DISK_NAME_LEN - 1] = '\0'; - if (create.flags != 0) { + if (create->flags != 0) { pr_err("nvm: no flags supported\n"); - return -EINVAL; + goto out; } - return __nvm_configure_create(&create); + ret = __nvm_configure_create(create); + +out: + kfree(create); + return ret; } static long nvm_ioctl_dev_remove(struct file *file, void __user *arg) diff --git a/drivers/lightnvm/rrpc.c b/drivers/lightnvm/rrpc.c index 4cc157a..9ed8374 100644 --- a/drivers/lightnvm/rrpc.c +++ b/drivers/lightnvm/rrpc.c @@ -1205,7 +1205,7 @@ static int rrpc_lun_init(struct rrpc *rrpc, struct rrpc_lun *rlun, return 0; } -static int rrpc_luns_init(struct rrpc *rrpc, int lun_begin, int lun_end) +static int rrpc_luns_init(struct rrpc *rrpc, struct nvm_ioctl_create_conf *conf) { struct nvm_dev *dev = rrpc->dev; struct rrpc_lun *rlun; @@ -1223,8 +1223,21 @@ static int rrpc_luns_init(struct rrpc *rrpc, int lun_begin, int lun_end) /* 1:1 mapping */ for (i = 0; i < rrpc->nr_luns; i++) { - int lunid = lun_begin + i; struct nvm_lun *lun; + int lunid; + + if (conf->type == NVM_CONFIG_TYPE_SIMPLE) + lunid = conf->s.lun_begin + i; + else if (conf->type == NVM_CONFIG_TYPE_LIST) + lunid = conf->l.lunid[i]; + else + goto err; + + if (lunid >= dev->nr_luns) { + pr_err("rrpc: lun out of bound (%u >= %u)\n", + lunid, dev->nr_luns); + goto err; + } if (dev->mt->reserve_lun(dev, lunid)) { pr_err("rrpc: lun %u is already allocated\n", lunid); @@ -1395,7 +1408,7 @@ err: static struct nvm_tgt_type tt_rrpc; static void *rrpc_init(struct nvm_dev *dev, struct gendisk *tdisk, - int lun_begin, int lun_end) + struct nvm_ioctl_create_conf *conf) { struct request_queue *bqueue = dev->q; struct request_queue *tqueue = tdisk->queue; @@ -1421,7 +1434,15 @@ static void *rrpc_init(struct nvm_dev *dev, struct gendisk *tdisk, spin_lock_init(&rrpc->bio_lock); INIT_WORK(&rrpc->ws_requeue, rrpc_requeue); - rrpc->nr_luns = lun_end - lun_begin + 1; + if (conf->type == NVM_CONFIG_TYPE_SIMPLE) + rrpc->nr_luns = conf->s.lun_end - conf->s.lun_begin + 1; + + else if (conf->type == NVM_CONFIG_TYPE_LIST) + rrpc->nr_luns = conf->l.nr_luns; + else { + kfree(rrpc); + return ERR_PTR(-EINVAL); + } /* simple round-robin strategy */ atomic_set(&rrpc->next_lun, -1); @@ -1433,7 +1454,7 @@ static void *rrpc_init(struct nvm_dev *dev, struct gendisk *tdisk, } rrpc->soffset = soffset; - ret = rrpc_luns_init(rrpc, lun_begin, lun_end); + ret = rrpc_luns_init(rrpc, conf); if (ret) { pr_err("nvm: rrpc: could not initialize luns\n"); goto err; diff --git a/include/linux/lightnvm.h b/include/linux/lightnvm.h index 419a3db..b941a8c 100644 --- a/include/linux/lightnvm.h +++ b/include/linux/lightnvm.h @@ -431,7 +431,8 @@ static inline int ppa_to_slc(struct nvm_dev *dev, int slc_pg) typedef blk_qc_t (nvm_tgt_make_rq_fn)(struct request_queue *, struct bio *); typedef sector_t (nvm_tgt_capacity_fn)(void *); -typedef void *(nvm_tgt_init_fn)(struct nvm_dev *, struct gendisk *, int, int); +typedef void *(nvm_tgt_init_fn)(struct nvm_dev *, struct gendisk *, + struct nvm_ioctl_create_conf *); typedef void (nvm_tgt_exit_fn)(void *); struct nvm_tgt_type { diff --git a/include/uapi/linux/lightnvm.h b/include/uapi/linux/lightnvm.h index 774a431..6dbf6a0 100644 --- a/include/uapi/linux/lightnvm.h +++ b/include/uapi/linux/lightnvm.h @@ -35,6 +35,8 @@ #define NVM_TTYPE_MAX 63 #define NVM_MMTYPE_LEN 8 +#define NVM_LUNS_MAX 768 + #define NVM_CTRL_FILE "/dev/lightnvm/control" struct nvm_ioctl_info_tgt { @@ -74,14 +76,21 @@ struct nvm_ioctl_create_simple { __u32 lun_end; }; +struct nvm_ioctl_create_list { + __u32 nr_luns; + __u32 lunid[NVM_LUNS_MAX]; +}; + enum { NVM_CONFIG_TYPE_SIMPLE = 0, + NVM_CONFIG_TYPE_LIST, }; struct nvm_ioctl_create_conf { __u32 type; union { struct nvm_ioctl_create_simple s; + struct nvm_ioctl_create_list l; }; };