[PATCH 14/15] nvme: enable FDP support
Keith Busch
kbusch at kernel.org
Tue Nov 19 10:17:36 PST 2024
On Tue, Nov 19, 2024 at 01:16:28PM +0100, Christoph Hellwig wrote:
> +static int nvme_read_fdp_config(struct nvme_ns *ns, struct nvme_ns_info *info)
> +{
> + struct nvme_fdp_config result;
> + struct nvme_fdp_config_log *log;
> + struct nvme_fdp_config_desc *configs;
> + size_t log_size;
> + int error;
> +
> + error = nvme_get_features(ns->ctrl, NVME_FEAT_FDP, info->endgid, NULL,
> + 0, &result);
> + if (error)
> + return error;
> +
> + if (!(result.flags & FDPCFG_FDPE)) {
> + dev_warn(ns->ctrl->device, "FDP not enable in current config\n");
> + return -EINVAL;
> + }
> +
> + log_size = sizeof(*log) + (result.fdpcidx + 1) * sizeof(*configs);
> + log = kmalloc(log_size, GFP_KERNEL);
> + if (!log)
> + return -ENOMEM;
> +
> + error = nvme_get_log_lsi(ns->ctrl, info->nsid, NVME_LOG_FDP_CONFIGS,
> + 0, 0, log, log_size, 0, info->endgid);
> + if (error) {
> + dev_warn(ns->ctrl->device,
> + "failed to read FDP config log: 0x%x\n", error);
> + goto out_free_log;
> + }
> +
> + if (le32_to_cpu(log->size) < log_size) {
> + dev_warn(ns->ctrl->device, "FDP log too small: %d vs %zd\n",
> + le32_to_cpu(log->size), log_size);
> + error = -EINVAL;
> + goto out_free_log;
> + }
> +
> + configs = (struct nvme_fdp_config_desc *)(log + 1);
> + if (le32_to_cpu(configs[result.fdpcidx].nrg) > 1) {
> + dev_warn(ns->ctrl->device, "FDP NRG > 1 not supported\n");
Why not support multiple reclaim groups?
> + return -EINVAL;
> + }
> + ns->head->runs = le64_to_cpu(configs[result.fdpcidx].runs);
The config descriptors are variable length, so you can't just index into
it. You have to read each index individually to get the next index's offset.
Something like:
struct nvme_fdp_config_desc *configs;
void *l;
int i;
...
l = log + 1;
for (i = 0; i < result.fdpcidx; i++) {
configs = l;
l += le16_to_cpu(configs->size);
}
ns->head->runs = le64_to_cpu(configs->runs);
More information about the Linux-nvme
mailing list