Message ID | 20220427160255.300418-6-p.raghav@samsung.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | [01/16] block: make blkdev_nr_zones and blk_queue_zone_no generic for npo2 zsze | expand |
On Wed, Apr 27, 2022 at 06:02:44PM +0200, Pankaj Raghav wrote: > Remove the condition which disallows non-power_of_2 zone size ZNS drive > to be updated and use generic method to calculate number of zones > instead of relying on log and shift based calculation on zone size. > > The power_of_2 calculation has been replaced directly with generic > calculation without special handling. Both modified functions are not > used in hot paths, they are only used during initialization & > revalidation of the ZNS device. > > Reviewed-by: Luis Chamberlain <mcgrof@kernel.org> > Signed-off-by: Pankaj Raghav <p.raghav@samsung.com> > --- > drivers/nvme/host/zns.c | 11 ++--------- > 1 file changed, 2 insertions(+), 9 deletions(-) > > diff --git a/drivers/nvme/host/zns.c b/drivers/nvme/host/zns.c > index 9f81beb4df4e..2087de0768ee 100644 > --- a/drivers/nvme/host/zns.c > +++ b/drivers/nvme/host/zns.c > @@ -101,13 +101,6 @@ int nvme_update_zone_info(struct nvme_ns *ns, unsigned lbaf) > } > > ns->zsze = nvme_lba_to_sect(ns, le64_to_cpu(id->lbafe[lbaf].zsze)); > - if (!is_power_of_2(ns->zsze)) { > - dev_warn(ns->ctrl->device, > - "invalid zone size:%llu for namespace:%u\n", > - ns->zsze, ns->head->ns_id); > - status = -ENODEV; > - goto free_data; > - } > > blk_queue_set_zoned(ns->disk, BLK_ZONED_HM); > blk_queue_flag_set(QUEUE_FLAG_ZONE_RESETALL, q); > @@ -129,7 +122,7 @@ static void *nvme_zns_alloc_report_buffer(struct nvme_ns *ns, > sizeof(struct nvme_zone_descriptor); > > nr_zones = min_t(unsigned int, nr_zones, > - get_capacity(ns->disk) >> ilog2(ns->zsze)); > + div64_u64(get_capacity(ns->disk), ns->zsze)); > > bufsize = sizeof(struct nvme_zone_report) + > nr_zones * sizeof(struct nvme_zone_descriptor); > @@ -197,7 +190,7 @@ int nvme_ns_report_zones(struct nvme_ns *ns, sector_t sector, > c.zmr.zrasf = NVME_ZRASF_ZONE_REPORT_ALL; > c.zmr.pr = NVME_REPORT_ZONE_PARTIAL; > > - sector &= ~(ns->zsze - 1); > + sector = rounddown(sector, ns->zsze); > while (zone_idx < nr_zones && sector < get_capacity(ns->disk)) { > memset(report, 0, buflen); > > -- > 2.25.1 > Looks good. Reviewed by: Adam Manzanares <a.manzanares@samsung.com>
On 4/27/22 09:02, Pankaj Raghav wrote: > - sector &= ~(ns->zsze - 1); > + sector = rounddown(sector, ns->zsze); The above change breaks 32-bit builds since ns->zsze is 64 bits wide and since rounddown() uses the C division operator instead of div64_u64(). Thanks, Bart.
On 2022-05-03 18:50, Bart Van Assche wrote: > On 4/27/22 09:02, Pankaj Raghav wrote: >> - sector &= ~(ns->zsze - 1); >> + sector = rounddown(sector, ns->zsze); > > The above change breaks 32-bit builds since ns->zsze is 64 bits wide and > since rounddown() uses the C division operator instead of div64_u64(). > Good catch. I don't see any generic helper for rounddown that will work for both 32 bits and 64 bits. Maybe I will open code the rounddown logic here so that it works for both 32 and 64 bits. > Thanks, > > Bart.
On 4/27/22 09:02, Pankaj Raghav wrote: > Remove the condition which disallows non-power_of_2 zone size ZNS drive > to be updated and use generic method to calculate number of zones > instead of relying on log and shift based calculation on zone size. > > The power_of_2 calculation has been replaced directly with generic > calculation without special handling. Both modified functions are not > used in hot paths, they are only used during initialization & > revalidation of the ZNS device. > > Reviewed-by: Luis Chamberlain <mcgrof@kernel.org> > Signed-off-by: Pankaj Raghav <p.raghav@samsung.com> > --- > drivers/nvme/host/zns.c | 11 ++--------- > 1 file changed, 2 insertions(+), 9 deletions(-) > > diff --git a/drivers/nvme/host/zns.c b/drivers/nvme/host/zns.c > index 9f81beb4df4e..2087de0768ee 100644 > --- a/drivers/nvme/host/zns.c > +++ b/drivers/nvme/host/zns.c > @@ -101,13 +101,6 @@ int nvme_update_zone_info(struct nvme_ns *ns, unsigned lbaf) > } > > ns->zsze = nvme_lba_to_sect(ns, le64_to_cpu(id->lbafe[lbaf].zsze)); > - if (!is_power_of_2(ns->zsze)) { > - dev_warn(ns->ctrl->device, > - "invalid zone size:%llu for namespace:%u\n", > - ns->zsze, ns->head->ns_id); > - status = -ENODEV; > - goto free_data; > - } > > blk_queue_set_zoned(ns->disk, BLK_ZONED_HM); > blk_queue_flag_set(QUEUE_FLAG_ZONE_RESETALL, q); > @@ -129,7 +122,7 @@ static void *nvme_zns_alloc_report_buffer(struct nvme_ns *ns, > sizeof(struct nvme_zone_descriptor); > > nr_zones = min_t(unsigned int, nr_zones, > - get_capacity(ns->disk) >> ilog2(ns->zsze)); > + div64_u64(get_capacity(ns->disk), ns->zsze)); > Same here; please add a helper calculating the number of zones for a given disk. > bufsize = sizeof(struct nvme_zone_report) + > nr_zones * sizeof(struct nvme_zone_descriptor); > @@ -197,7 +190,7 @@ int nvme_ns_report_zones(struct nvme_ns *ns, sector_t sector, > c.zmr.zrasf = NVME_ZRASF_ZONE_REPORT_ALL; > c.zmr.pr = NVME_REPORT_ZONE_PARTIAL; > > - sector &= ~(ns->zsze - 1); > + sector = rounddown(sector, ns->zsze); > while (zone_idx < nr_zones && sector < get_capacity(ns->disk)) { > memset(report, 0, buflen); > Please be a bit more consistent. In the previous patches you always had a condition to check if it's a power_of_2 zone size, but here you are using the same calculation for each disk. So please use the check in all locations, or add a comment why the generic calculation is okay to use here. Cheers, Hannes
On 2022-05-04 19:03, Hannes Reinecke wrote: > On 4/27/22 09:02, Pankaj Raghav wrote: >> Remove the condition which disallows non-power_of_2 zone size ZNS drive >> to be updated and use generic method to calculate number of zones >> instead of relying on log and shift based calculation on zone size. >> >> The power_of_2 calculation has been replaced directly with generic >> calculation without special handling. Both modified functions are not >> used in hot paths, they are only used during initialization & >> revalidation of the ZNS device. >> >> Reviewed-by: Luis Chamberlain <mcgrof@kernel.org> >> Signed-off-by: Pankaj Raghav <p.raghav@samsung.com> >> --- } >> ns->zsze = nvme_lba_to_sect(ns, >> le64_to_cpu(id->lbafe[lbaf].zsze)); >> - if (!is_power_of_2(ns->zsze)) { >> - dev_warn(ns->ctrl->device, >> - "invalid zone size:%llu for namespace:%u\n", >> - ns->zsze, ns->head->ns_id); >> - status = -ENODEV; >> - goto free_data; >> - } >> blk_queue_set_zoned(ns->disk, BLK_ZONED_HM); >> blk_queue_flag_set(QUEUE_FLAG_ZONE_RESETALL, q); >> @@ -129,7 +122,7 @@ static void *nvme_zns_alloc_report_buffer(struct >> nvme_ns *ns, >> sizeof(struct nvme_zone_descriptor); >> nr_zones = min_t(unsigned int, nr_zones, >> - get_capacity(ns->disk) >> ilog2(ns->zsze)); >> + div64_u64(get_capacity(ns->disk), ns->zsze)); >> > Same here; please add a helper calculating the number of zones for a > given disk. > I am already using the div64_u64 helper and this is not done again anywhere in the nvme zns driver. I am not sure if having a separate helper for this will add value. And this is not in the hot path, so no need for special handling. >> bufsize = sizeof(struct nvme_zone_report) + >> nr_zones * sizeof(struct nvme_zone_descriptor); >> @@ -197,7 +190,7 @@ int nvme_ns_report_zones(struct nvme_ns *ns, >> sector_t sector, >> c.zmr.zrasf = NVME_ZRASF_ZONE_REPORT_ALL; >> c.zmr.pr = NVME_REPORT_ZONE_PARTIAL; >> - sector &= ~(ns->zsze - 1); >> + sector = rounddown(sector, ns->zsze); >> while (zone_idx < nr_zones && sector < get_capacity(ns->disk)) { >> memset(report, 0, buflen); >> > Please be a bit more consistent. In the previous patches you always had > a condition to check if it's a power_of_2 zone size, but here you are > using the same calculation for each disk. > So please use the check in all locations, or add a comment why the > generic calculation is okay to use here. > That is a good point. I have mentioned that in my commit log that I am not having any special handling because these calculations are not in the hot path. Maybe adding comments is better for clarity. I will also do it for your previous comment. I will queue this up for my next revision. Thanks. > Cheers, > > Hannes
diff --git a/drivers/nvme/host/zns.c b/drivers/nvme/host/zns.c index 9f81beb4df4e..2087de0768ee 100644 --- a/drivers/nvme/host/zns.c +++ b/drivers/nvme/host/zns.c @@ -101,13 +101,6 @@ int nvme_update_zone_info(struct nvme_ns *ns, unsigned lbaf) } ns->zsze = nvme_lba_to_sect(ns, le64_to_cpu(id->lbafe[lbaf].zsze)); - if (!is_power_of_2(ns->zsze)) { - dev_warn(ns->ctrl->device, - "invalid zone size:%llu for namespace:%u\n", - ns->zsze, ns->head->ns_id); - status = -ENODEV; - goto free_data; - } blk_queue_set_zoned(ns->disk, BLK_ZONED_HM); blk_queue_flag_set(QUEUE_FLAG_ZONE_RESETALL, q); @@ -129,7 +122,7 @@ static void *nvme_zns_alloc_report_buffer(struct nvme_ns *ns, sizeof(struct nvme_zone_descriptor); nr_zones = min_t(unsigned int, nr_zones, - get_capacity(ns->disk) >> ilog2(ns->zsze)); + div64_u64(get_capacity(ns->disk), ns->zsze)); bufsize = sizeof(struct nvme_zone_report) + nr_zones * sizeof(struct nvme_zone_descriptor); @@ -197,7 +190,7 @@ int nvme_ns_report_zones(struct nvme_ns *ns, sector_t sector, c.zmr.zrasf = NVME_ZRASF_ZONE_REPORT_ALL; c.zmr.pr = NVME_REPORT_ZONE_PARTIAL; - sector &= ~(ns->zsze - 1); + sector = rounddown(sector, ns->zsze); while (zone_idx < nr_zones && sector < get_capacity(ns->disk)) { memset(report, 0, buflen);