From patchwork Mon Feb 10 22:20:45 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Alexey Dobriyan X-Patchwork-Id: 11374181 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 904E2138D for ; Mon, 10 Feb 2020 22:20:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 70F9D20714 for ; Mon, 10 Feb 2020 22:20:51 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="f4Cm5z/1" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727422AbgBJWUu (ORCPT ); Mon, 10 Feb 2020 17:20:50 -0500 Received: from mail-wr1-f65.google.com ([209.85.221.65]:47090 "EHLO mail-wr1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727385AbgBJWUu (ORCPT ); Mon, 10 Feb 2020 17:20:50 -0500 Received: by mail-wr1-f65.google.com with SMTP id z7so9712031wrl.13 for ; Mon, 10 Feb 2020 14:20:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=date:from:to:cc:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=0GPnstPH6DXeOW6ivPKBTV0ZmntX0HoiFnDoh6wA9dU=; b=f4Cm5z/1e+Zi3v9FOh8dVfbHLcL6BatIKIhJ7zTEEoLT+wfLpj2e5H4Uq4mOYhd73J AMGnnnVGbO+dZljBwAYXyBfizs+XnPEHc8XAcECWOM519ZJzdaTWK75+EeEnKhCzj8tG OJDt8Of4nVpHe2acGXPDD5Y8A+s9youMCOvLqvkn3jabNAwBWC2sQxezyQEGFVWPNDNY k68IQ+1SIuXx+bVcFV3szjV1EBUEv3N1KHY+PlMiLgzDU17ArMC3dXL7BLZ9P7FZ7W0d 4j74y98CbrjNDlgpz1RwE4OvRzXDD8c3osaJh5CQv2cunS9jLn6deR9IceVwlXm/2pXI y3Gg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:references :mime-version:content-disposition:in-reply-to:user-agent; bh=0GPnstPH6DXeOW6ivPKBTV0ZmntX0HoiFnDoh6wA9dU=; b=Fkw6LAWoW53RcW8gaXnP8nkx4+4JN8SescnYvhK2nInvltdy1iOuQJ3HuPB6QIrXpZ tQQha339sCRUVnBVOEZ+PxYc5Ssm+NUzKhViyT4sc0JfjO4OjvvNGaHOzijNrjJY0Euo PpLuBo/1BlFGeXqKYLd5qzKUNeiAOFd/Vvi0Yf01LLX0lr9vKdDq31LFTJJouWZk7LEC A58z84CsnTg+i0lMNhA07MPVyw+o2WKtDb8zxuYqqUjtaSQbHb7MMS9h4RUA4PvZ3y+G H71khCMykHn0vj501D0foEecE4+IXpjXdMG+EWSa6vyjHrFOiA406sdJPKsDUjBa2hpN htFw== X-Gm-Message-State: APjAAAX5tf/1ntZpFraBUnJCzVjpFPkKath14kjjTTOkedmJuXKg9vZj tbqWROcYniJureMaZfob+qkhZ8U= X-Google-Smtp-Source: APXvYqxyPfN/TUyI2lEr5/mjtaxTIX3FxJISgjXH6wMTNMbX+pnnlVywRnY2GeQzrSNiheSZjo4IZg== X-Received: by 2002:adf:b352:: with SMTP id k18mr4039736wrd.242.1581373248396; Mon, 10 Feb 2020 14:20:48 -0800 (PST) Received: from avx2 ([46.53.254.169]) by smtp.gmail.com with ESMTPSA id e17sm2166152wrn.62.2020.02.10.14.20.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Feb 2020 14:20:47 -0800 (PST) Date: Tue, 11 Feb 2020 01:20:45 +0300 From: Alexey Dobriyan To: axboe@kernel.dk Cc: linux-block@vger.kernel.org, damien.lemoal@wdc.com Subject: [PATCH v2] block: support arbitrary zone size Message-ID: <20200210222045.GA1495@avx2> References: <20200210220816.GA7769@avx2> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20200210220816.GA7769@avx2> User-Agent: Mutt/1.10.1 (2018-07-13) Sender: linux-block-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-block@vger.kernel.org SK hynix is going to ship ZNS device with zone size not being power of 2. Signed-off-by: Alexey Dobriyan (SK hynix) --- v2: fixup one ">>ilog2"/div conversion :-/ block/blk-settings.c | 4 +--- block/blk-zoned.c | 10 +++++----- drivers/block/null_blk_main.c | 11 ++++++----- drivers/block/null_blk_zoned.c | 10 ++-------- 4 files changed, 14 insertions(+), 21 deletions(-) --- a/block/blk-settings.c +++ b/block/blk-settings.c @@ -206,15 +206,13 @@ EXPORT_SYMBOL(blk_queue_max_hw_sectors); * * Description: * If a driver doesn't want IOs to cross a given chunk size, it can set - * this limit and prevent merging across chunks. Note that the chunk size - * must currently be a power-of-2 in sectors. Also note that the block + * this limit and prevent merging across chunks. Note that the block * layer must accept a page worth of data at any offset. So if the * crossing of chunks is a hard limitation in the driver, it must still be * prepared to split single page bios. **/ void blk_queue_chunk_sectors(struct request_queue *q, unsigned int chunk_sectors) { - BUG_ON(!is_power_of_2(chunk_sectors)); q->limits.chunk_sectors = chunk_sectors; } EXPORT_SYMBOL(blk_queue_chunk_sectors); --- a/block/blk-zoned.c +++ b/block/blk-zoned.c @@ -83,7 +83,7 @@ unsigned int blkdev_nr_zones(struct gendisk *disk) if (!blk_queue_is_zoned(disk->queue)) return 0; - return (get_capacity(disk) + zone_sectors - 1) >> ilog2(zone_sectors); + return div64_u64(get_capacity(disk) + zone_sectors - 1, zone_sectors); } EXPORT_SYMBOL_GPL(blkdev_nr_zones); @@ -363,14 +363,14 @@ static int blk_revalidate_zone_cb(struct blk_zone *zone, unsigned int idx, * smaller last zone. */ if (zone->start == 0) { - if (zone->len == 0 || !is_power_of_2(zone->len)) { - pr_warn("%s: Invalid zoned device with non power of two zone size (%llu)\n", - disk->disk_name, zone->len); + if (zone->len == 0) { + pr_warn("%s: Invalid zoned device with length 0\n", + disk->disk_name); return -ENODEV; } args->zone_sectors = zone->len; - args->nr_zones = (capacity + zone->len - 1) >> ilog2(zone->len); + args->nr_zones = div64_u64(capacity + zone->len - 1, zone->len); } else if (zone->start + args->zone_sectors < capacity) { if (zone->len != args->zone_sectors) { pr_warn("%s: Invalid zoned device with non constant zone size\n", --- a/drivers/block/null_blk_main.c +++ b/drivers/block/null_blk_main.c @@ -187,7 +187,7 @@ MODULE_PARM_DESC(zoned, "Make device as a host-managed zoned block device. Defau static unsigned long g_zone_size = 256; module_param_named(zone_size, g_zone_size, ulong, S_IRUGO); -MODULE_PARM_DESC(zone_size, "Zone size in MB when block device is zoned. Must be power-of-two: Default: 256"); +MODULE_PARM_DESC(zone_size, "Zone size in MB when block device is zoned. Default: 256"); static unsigned int g_zone_nr_conv; module_param_named(zone_nr_conv, g_zone_nr_conv, uint, 0444); @@ -1641,10 +1641,11 @@ static int null_validate_conf(struct nullb_device *dev) if (dev->queue_mode == NULL_Q_BIO) dev->mbps = 0; - if (dev->zoned && - (!dev->zone_size || !is_power_of_2(dev->zone_size))) { - pr_err("zone_size must be power-of-two\n"); - return -EINVAL; + if (dev->zoned) { + if (dev->zone_size == 0) { + pr_err("zone_size must be positive\n"); + return -EINVAL; + } } return 0; --- a/drivers/block/null_blk_zoned.c +++ b/drivers/block/null_blk_zoned.c @@ -7,7 +7,7 @@ static inline unsigned int null_zone_no(struct nullb_device *dev, sector_t sect) { - return sect >> ilog2(dev->zone_size_sects); + return div64_u64(sect, dev->zone_size_sects); } int null_zone_init(struct nullb_device *dev) @@ -16,14 +16,8 @@ int null_zone_init(struct nullb_device *dev) sector_t sector = 0; unsigned int i; - if (!is_power_of_2(dev->zone_size)) { - pr_err("zone_size must be power-of-two\n"); - return -EINVAL; - } - dev->zone_size_sects = dev->zone_size << ZONE_SIZE_SHIFT; - dev->nr_zones = dev_size >> - (SECTOR_SHIFT + ilog2(dev->zone_size_sects)); + dev->nr_zones = div64_u64(dev_size, dev->zone_size_sects * SECTOR_SIZE); dev->zones = kvmalloc_array(dev->nr_zones, sizeof(struct blk_zone), GFP_KERNEL | __GFP_ZERO); if (!dev->zones)