nvme: allow user toggling hmb usage
The NVMe host memory buffer may consume a non-negligable amount of memory. Controllers are required to function without the host memory buffer enabled, but with possibly degraded performance. Export a sysfs property to toggle this feature on a per-device granularity so users may choose to reclaim memory at the expense of storage performance. Signed-off-by: Keith Busch <kbusch@kernel.org> Reviewed-by: Sagi Grimberg <sagi@grimberg.me> Signed-off-by: Christoph Hellwig <hch@lst.de>
This commit is contained in:
parent
e5ad96f388
commit
a5df5e79c4
@ -137,6 +137,7 @@ struct nvme_dev {
|
||||
u32 cmbloc;
|
||||
struct nvme_ctrl ctrl;
|
||||
u32 last_ps;
|
||||
bool hmb;
|
||||
|
||||
mempool_t *iod_mempool;
|
||||
|
||||
@ -1896,7 +1897,9 @@ static int nvme_set_host_mem(struct nvme_dev *dev, u32 bits)
|
||||
dev_warn(dev->ctrl.device,
|
||||
"failed to set host mem (err %d, flags %#x).\n",
|
||||
ret, bits);
|
||||
}
|
||||
} else
|
||||
dev->hmb = bits & NVME_HOST_MEM_ENABLE;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -2081,6 +2084,42 @@ static ssize_t cmbsz_show(struct device *dev, struct device_attribute *attr,
|
||||
}
|
||||
static DEVICE_ATTR_RO(cmbsz);
|
||||
|
||||
static ssize_t hmb_show(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
struct nvme_dev *ndev = to_nvme_dev(dev_get_drvdata(dev));
|
||||
|
||||
return sysfs_emit(buf, "%d\n", ndev->hmb);
|
||||
}
|
||||
|
||||
static ssize_t hmb_store(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct nvme_dev *ndev = to_nvme_dev(dev_get_drvdata(dev));
|
||||
bool new;
|
||||
int ret;
|
||||
|
||||
if (strtobool(buf, &new) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (new == ndev->hmb)
|
||||
return count;
|
||||
|
||||
if (new) {
|
||||
ret = nvme_setup_host_mem(ndev);
|
||||
} else {
|
||||
ret = nvme_set_host_mem(ndev, 0);
|
||||
if (!ret)
|
||||
nvme_free_host_mem(ndev);
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
return count;
|
||||
}
|
||||
static DEVICE_ATTR_RW(hmb);
|
||||
|
||||
static umode_t nvme_pci_attrs_are_visible(struct kobject *kobj,
|
||||
struct attribute *a, int n)
|
||||
{
|
||||
@ -2094,6 +2133,9 @@ static umode_t nvme_pci_attrs_are_visible(struct kobject *kobj,
|
||||
if (!dev->cmbsz)
|
||||
return 0;
|
||||
}
|
||||
if (a == &dev_attr_hmb.attr && !ctrl->hmpre)
|
||||
return 0;
|
||||
|
||||
return a->mode;
|
||||
}
|
||||
|
||||
@ -2101,6 +2143,7 @@ static struct attribute *nvme_pci_attrs[] = {
|
||||
&dev_attr_cmb.attr,
|
||||
&dev_attr_cmbloc.attr,
|
||||
&dev_attr_cmbsz.attr,
|
||||
&dev_attr_hmb.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user