dmanegine: idxd: reformat opcap output to match bitmap_parse() input

To make input and output consistent and prepping for the per WQ operation
configuration support, change the output of opcap display to match the
input that is expected by bitmap_parse() helper function. The output will
be a bitmap with field width as the number of bits using the %*pb format
specifier for printk() family.

Signed-off-by: Dave Jiang <dave.jiang@intel.com>
Co-developed-by: Fenghua Yu <fenghua.yu@intel.com>
Signed-off-by: Fenghua Yu <fenghua.yu@intel.com>
Link: https://lore.kernel.org/r/20220917161222.2835172-3-fenghua.yu@intel.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>
This commit is contained in:
Dave Jiang 2022-09-17 09:12:19 -07:00 committed by Vinod Koul
parent 22bd0df846
commit a8563a33a5
4 changed files with 26 additions and 7 deletions

View File

@ -310,6 +310,8 @@ struct idxd_device {
struct work_struct work;
struct idxd_pmu *idxd_pmu;
unsigned long *opcap_bmap;
};
/* IDXD software descriptor */

View File

@ -375,6 +375,19 @@ static void idxd_read_table_offsets(struct idxd_device *idxd)
dev_dbg(dev, "IDXD Perfmon Offset: %#x\n", idxd->perfmon_offset);
}
static void multi_u64_to_bmap(unsigned long *bmap, u64 *val, int count)
{
int i, j, nr;
for (i = 0, nr = 0; i < count; i++) {
for (j = 0; j < BITS_PER_LONG_LONG; j++) {
if (val[i] & BIT(j))
set_bit(nr, bmap);
nr++;
}
}
}
static void idxd_read_caps(struct idxd_device *idxd)
{
struct device *dev = &idxd->pdev->dev;
@ -433,6 +446,7 @@ static void idxd_read_caps(struct idxd_device *idxd)
IDXD_OPCAP_OFFSET + i * sizeof(u64));
dev_dbg(dev, "opcap[%d]: %#llx\n", i, idxd->hw.opcap.bits[i]);
}
multi_u64_to_bmap(idxd->opcap_bmap, &idxd->hw.opcap.bits[0], 4);
}
static struct idxd_device *idxd_alloc(struct pci_dev *pdev, struct idxd_driver_data *data)
@ -454,6 +468,12 @@ static struct idxd_device *idxd_alloc(struct pci_dev *pdev, struct idxd_driver_d
if (idxd->id < 0)
return NULL;
idxd->opcap_bmap = bitmap_zalloc_node(IDXD_MAX_OPCAP_BITS, GFP_KERNEL, dev_to_node(dev));
if (!idxd->opcap_bmap) {
ida_free(&idxd_ida, idxd->id);
return NULL;
}
device_initialize(conf_dev);
conf_dev->parent = dev;
conf_dev->bus = &dsa_bus_type;

View File

@ -90,6 +90,8 @@ struct opcap {
u64 bits[4];
};
#define IDXD_MAX_OPCAP_BITS 256U
#define IDXD_OPCAP_OFFSET 0x40
#define IDXD_TABLE_OFFSET 0x60

View File

@ -1180,14 +1180,8 @@ static ssize_t op_cap_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct idxd_device *idxd = confdev_to_idxd(dev);
int i, rc = 0;
for (i = 0; i < 4; i++)
rc += sysfs_emit_at(buf, rc, "%#llx ", idxd->hw.opcap.bits[i]);
rc--;
rc += sysfs_emit_at(buf, rc, "\n");
return rc;
return sysfs_emit(buf, "%*pb\n", IDXD_MAX_OPCAP_BITS, idxd->opcap_bmap);
}
static DEVICE_ATTR_RO(op_cap);
@ -1412,6 +1406,7 @@ static void idxd_conf_device_release(struct device *dev)
kfree(idxd->wqs);
kfree(idxd->engines);
ida_free(&idxd_ida, idxd->id);
bitmap_free(idxd->opcap_bmap);
kfree(idxd);
}