^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* Copyright(c) 2019 Intel Corporation. All rights rsvd. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/io-64-nonatomic-lo-hi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <uapi/linux/idxd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include "registers.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include "idxd.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) static char *idxd_wq_type_names[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) [IDXD_WQT_NONE] = "none",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) [IDXD_WQT_KERNEL] = "kernel",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) [IDXD_WQT_USER] = "user",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) static void idxd_conf_device_release(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) dev_dbg(dev, "%s for %s\n", __func__, dev_name(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) static struct device_type idxd_group_device_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) .name = "group",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) .release = idxd_conf_device_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) static struct device_type idxd_wq_device_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) .name = "wq",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) .release = idxd_conf_device_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) static struct device_type idxd_engine_device_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) .name = "engine",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) .release = idxd_conf_device_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) static struct device_type dsa_device_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) .name = "dsa",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) .release = idxd_conf_device_release,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) static inline bool is_dsa_dev(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) return dev ? dev->type == &dsa_device_type : false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) static inline bool is_idxd_dev(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) return is_dsa_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) static inline bool is_idxd_wq_dev(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) return dev ? dev->type == &idxd_wq_device_type : false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) static inline bool is_idxd_wq_dmaengine(struct idxd_wq *wq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) if (wq->type == IDXD_WQT_KERNEL &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) strcmp(wq->name, "dmaengine") == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) static inline bool is_idxd_wq_cdev(struct idxd_wq *wq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) return wq->type == IDXD_WQT_USER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) static int idxd_config_bus_match(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) struct device_driver *drv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) int matched = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) if (is_idxd_dev(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) struct idxd_device *idxd = confdev_to_idxd(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) if (idxd->state != IDXD_DEV_CONF_READY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) matched = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) } else if (is_idxd_wq_dev(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) struct idxd_wq *wq = confdev_to_wq(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) struct idxd_device *idxd = wq->idxd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (idxd->state < IDXD_DEV_CONF_READY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (wq->state != IDXD_WQ_DISABLED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) dev_dbg(dev, "%s not disabled\n", dev_name(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) matched = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) if (matched)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) dev_dbg(dev, "%s matched\n", dev_name(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) return matched;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) static int idxd_config_bus_probe(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) dev_dbg(dev, "%s called\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) if (is_idxd_dev(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct idxd_device *idxd = confdev_to_idxd(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) if (idxd->state != IDXD_DEV_CONF_READY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) dev_warn(dev, "Device not ready for config\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) if (!try_module_get(THIS_MODULE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) /* Perform IDXD configuration and enabling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) spin_lock_irqsave(&idxd->dev_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) rc = idxd_device_config(idxd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) spin_unlock_irqrestore(&idxd->dev_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) module_put(THIS_MODULE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) dev_warn(dev, "Device config failed: %d\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) /* start device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) rc = idxd_device_enable(idxd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) module_put(THIS_MODULE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) dev_warn(dev, "Device enable failed: %d\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) dev_info(dev, "Device %s enabled\n", dev_name(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) rc = idxd_register_dma_device(idxd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) module_put(THIS_MODULE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) dev_dbg(dev, "Failed to register dmaengine device\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) } else if (is_idxd_wq_dev(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) struct idxd_wq *wq = confdev_to_wq(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) struct idxd_device *idxd = wq->idxd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) mutex_lock(&wq->wq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if (idxd->state != IDXD_DEV_ENABLED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) mutex_unlock(&wq->wq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) dev_warn(dev, "Enabling while device not enabled.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (wq->state != IDXD_WQ_DISABLED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) mutex_unlock(&wq->wq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) dev_warn(dev, "WQ %d already enabled.\n", wq->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) if (!wq->group) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) mutex_unlock(&wq->wq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) dev_warn(dev, "WQ not attached to group.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) if (strlen(wq->name) == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) mutex_unlock(&wq->wq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) dev_warn(dev, "WQ name not set.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) rc = idxd_wq_alloc_resources(wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) mutex_unlock(&wq->wq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) dev_warn(dev, "WQ resource alloc failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) spin_lock_irqsave(&idxd->dev_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) rc = idxd_device_config(idxd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) spin_unlock_irqrestore(&idxd->dev_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) mutex_unlock(&wq->wq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) dev_warn(dev, "Writing WQ %d config failed: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) wq->id, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) rc = idxd_wq_enable(wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) mutex_unlock(&wq->wq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) dev_warn(dev, "WQ %d enabling failed: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) wq->id, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) rc = idxd_wq_map_portal(wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) dev_warn(dev, "wq portal mapping failed: %d\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) rc = idxd_wq_disable(wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) dev_warn(dev, "IDXD wq disable failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) mutex_unlock(&wq->wq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) wq->client_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) dev_info(dev, "wq %s enabled\n", dev_name(&wq->conf_dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) if (is_idxd_wq_dmaengine(wq)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) rc = idxd_register_dma_channel(wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) dev_dbg(dev, "DMA channel register failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) mutex_unlock(&wq->wq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) } else if (is_idxd_wq_cdev(wq)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) rc = idxd_wq_add_cdev(wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) dev_dbg(dev, "Cdev creation failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) mutex_unlock(&wq->wq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) mutex_unlock(&wq->wq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) static void disable_wq(struct idxd_wq *wq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) struct idxd_device *idxd = wq->idxd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) struct device *dev = &idxd->pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) mutex_lock(&wq->wq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) dev_dbg(dev, "%s removing WQ %s\n", __func__, dev_name(&wq->conf_dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) if (wq->state == IDXD_WQ_DISABLED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) mutex_unlock(&wq->wq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) if (is_idxd_wq_dmaengine(wq))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) idxd_unregister_dma_channel(wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) else if (is_idxd_wq_cdev(wq))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) idxd_wq_del_cdev(wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) if (idxd_wq_refcount(wq))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) dev_warn(dev, "Clients has claim on wq %d: %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) wq->id, idxd_wq_refcount(wq));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) idxd_wq_unmap_portal(wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) idxd_wq_drain(wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) idxd_wq_reset(wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) idxd_wq_free_resources(wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) wq->client_count = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) mutex_unlock(&wq->wq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) dev_info(dev, "wq %s disabled\n", dev_name(&wq->conf_dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) static int idxd_config_bus_remove(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) dev_dbg(dev, "%s called for %s\n", __func__, dev_name(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) /* disable workqueue here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) if (is_idxd_wq_dev(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) struct idxd_wq *wq = confdev_to_wq(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) disable_wq(wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) } else if (is_idxd_dev(dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) struct idxd_device *idxd = confdev_to_idxd(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) dev_dbg(dev, "%s removing dev %s\n", __func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) dev_name(&idxd->conf_dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) for (i = 0; i < idxd->max_wqs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) struct idxd_wq *wq = &idxd->wqs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) if (wq->state == IDXD_WQ_DISABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) dev_warn(dev, "Active wq %d on disable %s.\n", i,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) dev_name(&idxd->conf_dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) device_release_driver(&wq->conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) idxd_unregister_dma_device(idxd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) rc = idxd_device_disable(idxd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) for (i = 0; i < idxd->max_wqs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) struct idxd_wq *wq = &idxd->wqs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) mutex_lock(&wq->wq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) idxd_wq_disable_cleanup(wq);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) mutex_unlock(&wq->wq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) module_put(THIS_MODULE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) dev_warn(dev, "Device disable failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) dev_info(dev, "Device %s disabled\n", dev_name(dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) static void idxd_config_bus_shutdown(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) dev_dbg(dev, "%s called\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) struct bus_type dsa_bus_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) .name = "dsa",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) .match = idxd_config_bus_match,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) .probe = idxd_config_bus_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) .remove = idxd_config_bus_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) .shutdown = idxd_config_bus_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) static struct bus_type *idxd_bus_types[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) &dsa_bus_type
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) static struct idxd_device_driver dsa_drv = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) .drv = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) .name = "dsa",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) .bus = &dsa_bus_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) .owner = THIS_MODULE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) .mod_name = KBUILD_MODNAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) static struct idxd_device_driver *idxd_drvs[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) &dsa_drv
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) struct bus_type *idxd_get_bus_type(struct idxd_device *idxd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) return idxd_bus_types[idxd->type];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) static struct device_type *idxd_get_device_type(struct idxd_device *idxd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) if (idxd->type == IDXD_TYPE_DSA)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) return &dsa_device_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) /* IDXD generic driver setup */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) int idxd_register_driver(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) int i, rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) for (i = 0; i < IDXD_TYPE_MAX; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) rc = driver_register(&idxd_drvs[i]->drv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) goto drv_fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) drv_fail:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) while (--i >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) driver_unregister(&idxd_drvs[i]->drv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) void idxd_unregister_driver(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) for (i = 0; i < IDXD_TYPE_MAX; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) driver_unregister(&idxd_drvs[i]->drv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) /* IDXD engine attributes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) static ssize_t engine_group_id_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) struct idxd_engine *engine =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) container_of(dev, struct idxd_engine, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) if (engine->group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) return sprintf(buf, "%d\n", engine->group->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) return sprintf(buf, "%d\n", -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) static ssize_t engine_group_id_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) struct idxd_engine *engine =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) container_of(dev, struct idxd_engine, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) struct idxd_device *idxd = engine->idxd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) long id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) struct idxd_group *prevg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) rc = kstrtol(buf, 10, &id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) if (!test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) if (id > idxd->max_groups - 1 || id < -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) if (id == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if (engine->group) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) engine->group->num_engines--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) engine->group = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) prevg = engine->group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) if (prevg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) prevg->num_engines--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) engine->group = &idxd->groups[id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) engine->group->num_engines++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) static struct device_attribute dev_attr_engine_group =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) __ATTR(group_id, 0644, engine_group_id_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) engine_group_id_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) static struct attribute *idxd_engine_attributes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) &dev_attr_engine_group.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) static const struct attribute_group idxd_engine_attribute_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) .attrs = idxd_engine_attributes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) static const struct attribute_group *idxd_engine_attribute_groups[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) &idxd_engine_attribute_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) /* Group attributes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) static void idxd_set_free_tokens(struct idxd_device *idxd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) int i, tokens;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) for (i = 0, tokens = 0; i < idxd->max_groups; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) struct idxd_group *g = &idxd->groups[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) tokens += g->tokens_reserved;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) idxd->nr_tokens = idxd->max_tokens - tokens;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) static ssize_t group_tokens_reserved_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) struct idxd_group *group =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) container_of(dev, struct idxd_group, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) return sprintf(buf, "%u\n", group->tokens_reserved);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) static ssize_t group_tokens_reserved_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) struct idxd_group *group =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) container_of(dev, struct idxd_group, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) struct idxd_device *idxd = group->idxd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) rc = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) if (!test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) if (idxd->state == IDXD_DEV_ENABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) if (val > idxd->max_tokens)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) if (val > idxd->nr_tokens + group->tokens_reserved)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) group->tokens_reserved = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) idxd_set_free_tokens(idxd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) static struct device_attribute dev_attr_group_tokens_reserved =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) __ATTR(tokens_reserved, 0644, group_tokens_reserved_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) group_tokens_reserved_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) static ssize_t group_tokens_allowed_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) struct idxd_group *group =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) container_of(dev, struct idxd_group, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) return sprintf(buf, "%u\n", group->tokens_allowed);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) static ssize_t group_tokens_allowed_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) struct idxd_group *group =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) container_of(dev, struct idxd_group, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) struct idxd_device *idxd = group->idxd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) rc = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) if (!test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) if (idxd->state == IDXD_DEV_ENABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) if (val < 4 * group->num_engines ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) val > group->tokens_reserved + idxd->nr_tokens)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) group->tokens_allowed = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) static struct device_attribute dev_attr_group_tokens_allowed =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) __ATTR(tokens_allowed, 0644, group_tokens_allowed_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) group_tokens_allowed_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) static ssize_t group_use_token_limit_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) struct idxd_group *group =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) container_of(dev, struct idxd_group, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) return sprintf(buf, "%u\n", group->use_token_limit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) static ssize_t group_use_token_limit_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) struct idxd_group *group =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) container_of(dev, struct idxd_group, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) struct idxd_device *idxd = group->idxd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) rc = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) if (!test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) if (idxd->state == IDXD_DEV_ENABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) if (idxd->token_limit == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) group->use_token_limit = !!val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) static struct device_attribute dev_attr_group_use_token_limit =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) __ATTR(use_token_limit, 0644, group_use_token_limit_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) group_use_token_limit_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) static ssize_t group_engines_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) struct idxd_group *group =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) container_of(dev, struct idxd_group, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) int i, rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) char *tmp = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) struct idxd_device *idxd = group->idxd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) for (i = 0; i < idxd->max_engines; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) struct idxd_engine *engine = &idxd->engines[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) if (!engine->group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) if (engine->group->id == group->id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) rc += sprintf(tmp + rc, "engine%d.%d ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) idxd->id, engine->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) rc--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) rc += sprintf(tmp + rc, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) static struct device_attribute dev_attr_group_engines =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) __ATTR(engines, 0444, group_engines_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) static ssize_t group_work_queues_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) struct idxd_group *group =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) container_of(dev, struct idxd_group, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) int i, rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) char *tmp = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) struct idxd_device *idxd = group->idxd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) for (i = 0; i < idxd->max_wqs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) struct idxd_wq *wq = &idxd->wqs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) if (!wq->group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) if (wq->group->id == group->id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) rc += sprintf(tmp + rc, "wq%d.%d ",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) idxd->id, wq->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) rc--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) rc += sprintf(tmp + rc, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) static struct device_attribute dev_attr_group_work_queues =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) __ATTR(work_queues, 0444, group_work_queues_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) static ssize_t group_traffic_class_a_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) struct idxd_group *group =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) container_of(dev, struct idxd_group, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) return sprintf(buf, "%d\n", group->tc_a);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) static ssize_t group_traffic_class_a_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) struct idxd_group *group =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) container_of(dev, struct idxd_group, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) struct idxd_device *idxd = group->idxd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) rc = kstrtol(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) if (!test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) if (idxd->state == IDXD_DEV_ENABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) if (val < 0 || val > 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) group->tc_a = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) static struct device_attribute dev_attr_group_traffic_class_a =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) __ATTR(traffic_class_a, 0644, group_traffic_class_a_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) group_traffic_class_a_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) static ssize_t group_traffic_class_b_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) struct idxd_group *group =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) container_of(dev, struct idxd_group, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) return sprintf(buf, "%d\n", group->tc_b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) static ssize_t group_traffic_class_b_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) struct idxd_group *group =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) container_of(dev, struct idxd_group, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) struct idxd_device *idxd = group->idxd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) rc = kstrtol(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) if (!test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) if (idxd->state == IDXD_DEV_ENABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) if (val < 0 || val > 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) group->tc_b = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) static struct device_attribute dev_attr_group_traffic_class_b =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) __ATTR(traffic_class_b, 0644, group_traffic_class_b_show,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) group_traffic_class_b_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) static struct attribute *idxd_group_attributes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) &dev_attr_group_work_queues.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) &dev_attr_group_engines.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) &dev_attr_group_use_token_limit.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) &dev_attr_group_tokens_allowed.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) &dev_attr_group_tokens_reserved.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) &dev_attr_group_traffic_class_a.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) &dev_attr_group_traffic_class_b.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) static const struct attribute_group idxd_group_attribute_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) .attrs = idxd_group_attributes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) static const struct attribute_group *idxd_group_attribute_groups[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) &idxd_group_attribute_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) /* IDXD work queue attribs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) static ssize_t wq_clients_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) return sprintf(buf, "%d\n", wq->client_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) static struct device_attribute dev_attr_wq_clients =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) __ATTR(clients, 0444, wq_clients_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) static ssize_t wq_state_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) switch (wq->state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) case IDXD_WQ_DISABLED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) return sprintf(buf, "disabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) case IDXD_WQ_ENABLED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) return sprintf(buf, "enabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) return sprintf(buf, "unknown\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) static struct device_attribute dev_attr_wq_state =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) __ATTR(state, 0444, wq_state_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) static ssize_t wq_group_id_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) if (wq->group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) return sprintf(buf, "%u\n", wq->group->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) return sprintf(buf, "-1\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) static ssize_t wq_group_id_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) struct idxd_device *idxd = wq->idxd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) long id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) struct idxd_group *prevg, *group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) rc = kstrtol(buf, 10, &id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) if (!test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) if (wq->state != IDXD_WQ_DISABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) if (id > idxd->max_groups - 1 || id < -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) if (id == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) if (wq->group) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) wq->group->num_wqs--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) wq->group = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) group = &idxd->groups[id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) prevg = wq->group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) if (prevg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) prevg->num_wqs--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) wq->group = group;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) group->num_wqs++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) static struct device_attribute dev_attr_wq_group_id =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) __ATTR(group_id, 0644, wq_group_id_show, wq_group_id_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) static ssize_t wq_mode_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) return sprintf(buf, "%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) wq_dedicated(wq) ? "dedicated" : "shared");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) static ssize_t wq_mode_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) struct device_attribute *attr, const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) struct idxd_device *idxd = wq->idxd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) if (!test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) if (wq->state != IDXD_WQ_DISABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) if (sysfs_streq(buf, "dedicated")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) set_bit(WQ_FLAG_DEDICATED, &wq->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) wq->threshold = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) static struct device_attribute dev_attr_wq_mode =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) __ATTR(mode, 0644, wq_mode_show, wq_mode_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) static ssize_t wq_size_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) return sprintf(buf, "%u\n", wq->size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) static int total_claimed_wq_size(struct idxd_device *idxd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) int wq_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) for (i = 0; i < idxd->max_wqs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) struct idxd_wq *wq = &idxd->wqs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) wq_size += wq->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) return wq_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) static ssize_t wq_size_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) struct device_attribute *attr, const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) unsigned long size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) struct idxd_device *idxd = wq->idxd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) rc = kstrtoul(buf, 10, &size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) if (!test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) if (idxd->state == IDXD_DEV_ENABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) if (size + total_claimed_wq_size(idxd) - wq->size > idxd->max_wq_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) wq->size = size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) static struct device_attribute dev_attr_wq_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) __ATTR(size, 0644, wq_size_show, wq_size_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) static ssize_t wq_priority_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) return sprintf(buf, "%u\n", wq->priority);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) static ssize_t wq_priority_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) unsigned long prio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) struct idxd_device *idxd = wq->idxd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) rc = kstrtoul(buf, 10, &prio);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) if (!test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) if (wq->state != IDXD_WQ_DISABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) if (prio > IDXD_MAX_PRIORITY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) wq->priority = prio;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) static struct device_attribute dev_attr_wq_priority =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) __ATTR(priority, 0644, wq_priority_show, wq_priority_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) static ssize_t wq_type_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) switch (wq->type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) case IDXD_WQT_KERNEL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) return sprintf(buf, "%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) idxd_wq_type_names[IDXD_WQT_KERNEL]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) case IDXD_WQT_USER:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) return sprintf(buf, "%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) idxd_wq_type_names[IDXD_WQT_USER]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) case IDXD_WQT_NONE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) return sprintf(buf, "%s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) idxd_wq_type_names[IDXD_WQT_NONE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) static ssize_t wq_type_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) struct device_attribute *attr, const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) enum idxd_wq_type old_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) if (wq->state != IDXD_WQ_DISABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) old_type = wq->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) if (sysfs_streq(buf, idxd_wq_type_names[IDXD_WQT_NONE]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) wq->type = IDXD_WQT_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) else if (sysfs_streq(buf, idxd_wq_type_names[IDXD_WQT_KERNEL]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) wq->type = IDXD_WQT_KERNEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) else if (sysfs_streq(buf, idxd_wq_type_names[IDXD_WQT_USER]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) wq->type = IDXD_WQT_USER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) /* If we are changing queue type, clear the name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) if (wq->type != old_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) memset(wq->name, 0, WQ_NAME_SIZE + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) static struct device_attribute dev_attr_wq_type =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) __ATTR(type, 0644, wq_type_show, wq_type_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) static ssize_t wq_name_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) return sprintf(buf, "%s\n", wq->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) static ssize_t wq_name_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) struct device_attribute *attr, const char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) if (wq->state != IDXD_WQ_DISABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) if (strlen(buf) > WQ_NAME_SIZE || strlen(buf) == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) memset(wq->name, 0, WQ_NAME_SIZE + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) strncpy(wq->name, buf, WQ_NAME_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) strreplace(wq->name, '\n', '\0');
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) static struct device_attribute dev_attr_wq_name =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) __ATTR(name, 0644, wq_name_show, wq_name_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) static ssize_t wq_cdev_minor_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) int minor = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) mutex_lock(&wq->wq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) if (wq->idxd_cdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) minor = wq->idxd_cdev->minor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) mutex_unlock(&wq->wq_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) if (minor == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) return -ENXIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) return sysfs_emit(buf, "%d\n", minor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) static struct device_attribute dev_attr_wq_cdev_minor =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) __ATTR(cdev_minor, 0444, wq_cdev_minor_show, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) static int __get_sysfs_u64(const char *buf, u64 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) rc = kstrtou64(buf, 0, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) if (*val == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) *val = roundup_pow_of_two(*val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) static ssize_t wq_max_transfer_size_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) return sprintf(buf, "%llu\n", wq->max_xfer_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) static ssize_t wq_max_transfer_size_store(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) struct idxd_device *idxd = wq->idxd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) u64 xfer_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) if (wq->state != IDXD_WQ_DISABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) rc = __get_sysfs_u64(buf, &xfer_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) if (xfer_size > idxd->max_xfer_bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) wq->max_xfer_bytes = xfer_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) static struct device_attribute dev_attr_wq_max_transfer_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) __ATTR(max_transfer_size, 0644,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) wq_max_transfer_size_show, wq_max_transfer_size_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) static ssize_t wq_max_batch_size_show(struct device *dev, struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) return sprintf(buf, "%u\n", wq->max_batch_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) static ssize_t wq_max_batch_size_store(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) struct idxd_wq *wq = container_of(dev, struct idxd_wq, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) struct idxd_device *idxd = wq->idxd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) u64 batch_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) if (wq->state != IDXD_WQ_DISABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) rc = __get_sysfs_u64(buf, &batch_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) if (batch_size > idxd->max_batch_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) wq->max_batch_size = (u32)batch_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) static struct device_attribute dev_attr_wq_max_batch_size =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) __ATTR(max_batch_size, 0644, wq_max_batch_size_show, wq_max_batch_size_store);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) static struct attribute *idxd_wq_attributes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) &dev_attr_wq_clients.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) &dev_attr_wq_state.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) &dev_attr_wq_group_id.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) &dev_attr_wq_mode.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) &dev_attr_wq_size.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) &dev_attr_wq_priority.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) &dev_attr_wq_type.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) &dev_attr_wq_name.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) &dev_attr_wq_cdev_minor.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) &dev_attr_wq_max_transfer_size.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) &dev_attr_wq_max_batch_size.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) static const struct attribute_group idxd_wq_attribute_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) .attrs = idxd_wq_attributes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) static const struct attribute_group *idxd_wq_attribute_groups[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) &idxd_wq_attribute_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) /* IDXD device attribs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) static ssize_t version_show(struct device *dev, struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) struct idxd_device *idxd =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) container_of(dev, struct idxd_device, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) return sprintf(buf, "%#x\n", idxd->hw.version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) static DEVICE_ATTR_RO(version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) static ssize_t max_work_queues_size_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) struct idxd_device *idxd =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) container_of(dev, struct idxd_device, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) return sprintf(buf, "%u\n", idxd->max_wq_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) static DEVICE_ATTR_RO(max_work_queues_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) static ssize_t max_groups_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) struct idxd_device *idxd =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) container_of(dev, struct idxd_device, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) return sprintf(buf, "%u\n", idxd->max_groups);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) static DEVICE_ATTR_RO(max_groups);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) static ssize_t max_work_queues_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) struct idxd_device *idxd =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) container_of(dev, struct idxd_device, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) return sprintf(buf, "%u\n", idxd->max_wqs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) static DEVICE_ATTR_RO(max_work_queues);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) static ssize_t max_engines_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) struct idxd_device *idxd =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) container_of(dev, struct idxd_device, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) return sprintf(buf, "%u\n", idxd->max_engines);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) static DEVICE_ATTR_RO(max_engines);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) static ssize_t numa_node_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) struct idxd_device *idxd =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) container_of(dev, struct idxd_device, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) return sprintf(buf, "%d\n", dev_to_node(&idxd->pdev->dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) static DEVICE_ATTR_RO(numa_node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) static ssize_t max_batch_size_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) struct idxd_device *idxd =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) container_of(dev, struct idxd_device, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) return sprintf(buf, "%u\n", idxd->max_batch_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) static DEVICE_ATTR_RO(max_batch_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) static ssize_t max_transfer_size_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) struct idxd_device *idxd =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) container_of(dev, struct idxd_device, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) return sprintf(buf, "%llu\n", idxd->max_xfer_bytes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) static DEVICE_ATTR_RO(max_transfer_size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) static ssize_t op_cap_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) struct idxd_device *idxd =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) container_of(dev, struct idxd_device, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) int i, rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) for (i = 0; i < 4; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) rc += sysfs_emit_at(buf, rc, "%#llx ", idxd->hw.opcap.bits[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) rc--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) rc += sysfs_emit_at(buf, rc, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) static DEVICE_ATTR_RO(op_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) static ssize_t gen_cap_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) struct idxd_device *idxd =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) container_of(dev, struct idxd_device, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) return sprintf(buf, "%#llx\n", idxd->hw.gen_cap.bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) static DEVICE_ATTR_RO(gen_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) static ssize_t configurable_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) struct idxd_device *idxd =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) container_of(dev, struct idxd_device, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) return sprintf(buf, "%u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) static DEVICE_ATTR_RO(configurable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) static ssize_t clients_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) struct idxd_device *idxd =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) container_of(dev, struct idxd_device, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) int count = 0, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) spin_lock_irqsave(&idxd->dev_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) for (i = 0; i < idxd->max_wqs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) struct idxd_wq *wq = &idxd->wqs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) count += wq->client_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) spin_unlock_irqrestore(&idxd->dev_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) return sprintf(buf, "%d\n", count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) static DEVICE_ATTR_RO(clients);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) static ssize_t state_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) struct idxd_device *idxd =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) container_of(dev, struct idxd_device, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) switch (idxd->state) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) case IDXD_DEV_DISABLED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) case IDXD_DEV_CONF_READY:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) return sprintf(buf, "disabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) case IDXD_DEV_ENABLED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) return sprintf(buf, "enabled\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) case IDXD_DEV_HALTED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) return sprintf(buf, "halted\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) return sprintf(buf, "unknown\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) static DEVICE_ATTR_RO(state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) static ssize_t errors_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) struct idxd_device *idxd =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) container_of(dev, struct idxd_device, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) int i, out = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) spin_lock_irqsave(&idxd->dev_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) for (i = 0; i < 4; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) out += sprintf(buf + out, "%#018llx ", idxd->sw_err.bits[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) spin_unlock_irqrestore(&idxd->dev_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) out--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) out += sprintf(buf + out, "\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) return out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) static DEVICE_ATTR_RO(errors);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) static ssize_t max_tokens_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) struct idxd_device *idxd =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) container_of(dev, struct idxd_device, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) return sprintf(buf, "%u\n", idxd->max_tokens);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) static DEVICE_ATTR_RO(max_tokens);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) static ssize_t token_limit_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) struct idxd_device *idxd =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) container_of(dev, struct idxd_device, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) return sprintf(buf, "%u\n", idxd->token_limit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) static ssize_t token_limit_store(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) struct device_attribute *attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) const char *buf, size_t count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) struct idxd_device *idxd =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) container_of(dev, struct idxd_device, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) unsigned long val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) rc = kstrtoul(buf, 10, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) if (idxd->state == IDXD_DEV_ENABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) if (!test_bit(IDXD_FLAG_CONFIGURABLE, &idxd->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) if (!idxd->hw.group_cap.token_limit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) return -EPERM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) if (val > idxd->hw.group_cap.total_tokens)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) idxd->token_limit = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) return count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) static DEVICE_ATTR_RW(token_limit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) static ssize_t cdev_major_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) struct idxd_device *idxd =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) container_of(dev, struct idxd_device, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) return sprintf(buf, "%u\n", idxd->major);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) static DEVICE_ATTR_RO(cdev_major);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) static ssize_t cmd_status_show(struct device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) struct device_attribute *attr, char *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) struct idxd_device *idxd = container_of(dev, struct idxd_device, conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) return sprintf(buf, "%#x\n", idxd->cmd_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) static DEVICE_ATTR_RO(cmd_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) static struct attribute *idxd_device_attributes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) &dev_attr_version.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) &dev_attr_max_groups.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) &dev_attr_max_work_queues.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) &dev_attr_max_work_queues_size.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) &dev_attr_max_engines.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) &dev_attr_numa_node.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) &dev_attr_max_batch_size.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) &dev_attr_max_transfer_size.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) &dev_attr_op_cap.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) &dev_attr_gen_cap.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) &dev_attr_configurable.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) &dev_attr_clients.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) &dev_attr_state.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) &dev_attr_errors.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) &dev_attr_max_tokens.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) &dev_attr_token_limit.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) &dev_attr_cdev_major.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) &dev_attr_cmd_status.attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) static const struct attribute_group idxd_device_attribute_group = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) .attrs = idxd_device_attributes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) static const struct attribute_group *idxd_attribute_groups[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) &idxd_device_attribute_group,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) static int idxd_setup_engine_sysfs(struct idxd_device *idxd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) struct device *dev = &idxd->pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) int i, rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) for (i = 0; i < idxd->max_engines; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) struct idxd_engine *engine = &idxd->engines[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) engine->conf_dev.parent = &idxd->conf_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) dev_set_name(&engine->conf_dev, "engine%d.%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) idxd->id, engine->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) engine->conf_dev.bus = idxd_get_bus_type(idxd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) engine->conf_dev.groups = idxd_engine_attribute_groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) engine->conf_dev.type = &idxd_engine_device_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) dev_dbg(dev, "Engine device register: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) dev_name(&engine->conf_dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) rc = device_register(&engine->conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) put_device(&engine->conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) cleanup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) while (i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) struct idxd_engine *engine = &idxd->engines[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) device_unregister(&engine->conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) static int idxd_setup_group_sysfs(struct idxd_device *idxd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) struct device *dev = &idxd->pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) int i, rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) for (i = 0; i < idxd->max_groups; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) struct idxd_group *group = &idxd->groups[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) group->conf_dev.parent = &idxd->conf_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) dev_set_name(&group->conf_dev, "group%d.%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) idxd->id, group->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) group->conf_dev.bus = idxd_get_bus_type(idxd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) group->conf_dev.groups = idxd_group_attribute_groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) group->conf_dev.type = &idxd_group_device_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) dev_dbg(dev, "Group device register: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) dev_name(&group->conf_dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) rc = device_register(&group->conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) put_device(&group->conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) cleanup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) while (i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) struct idxd_group *group = &idxd->groups[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) device_unregister(&group->conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) static int idxd_setup_wq_sysfs(struct idxd_device *idxd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) struct device *dev = &idxd->pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) int i, rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) for (i = 0; i < idxd->max_wqs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) struct idxd_wq *wq = &idxd->wqs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) wq->conf_dev.parent = &idxd->conf_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) dev_set_name(&wq->conf_dev, "wq%d.%d", idxd->id, wq->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) wq->conf_dev.bus = idxd_get_bus_type(idxd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) wq->conf_dev.groups = idxd_wq_attribute_groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) wq->conf_dev.type = &idxd_wq_device_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) dev_dbg(dev, "WQ device register: %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) dev_name(&wq->conf_dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) rc = device_register(&wq->conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) put_device(&wq->conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) goto cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) cleanup:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) while (i--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) struct idxd_wq *wq = &idxd->wqs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) device_unregister(&wq->conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) static int idxd_setup_device_sysfs(struct idxd_device *idxd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) struct device *dev = &idxd->pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) char devname[IDXD_NAME_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) sprintf(devname, "%s%d", idxd_get_dev_name(idxd), idxd->id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) idxd->conf_dev.parent = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) dev_set_name(&idxd->conf_dev, "%s", devname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) idxd->conf_dev.bus = idxd_get_bus_type(idxd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) idxd->conf_dev.groups = idxd_attribute_groups;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) idxd->conf_dev.type = idxd_get_device_type(idxd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) dev_dbg(dev, "IDXD device register: %s\n", dev_name(&idxd->conf_dev));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) rc = device_register(&idxd->conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) put_device(&idxd->conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) int idxd_setup_sysfs(struct idxd_device *idxd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) struct device *dev = &idxd->pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) rc = idxd_setup_device_sysfs(idxd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) dev_dbg(dev, "Device sysfs registering failed: %d\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) rc = idxd_setup_wq_sysfs(idxd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) /* unregister conf dev */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) dev_dbg(dev, "Work Queue sysfs registering failed: %d\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) rc = idxd_setup_group_sysfs(idxd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) /* unregister conf dev */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) dev_dbg(dev, "Group sysfs registering failed: %d\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) rc = idxd_setup_engine_sysfs(idxd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) /* unregister conf dev */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) dev_dbg(dev, "Engine sysfs registering failed: %d\n", rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) void idxd_cleanup_sysfs(struct idxd_device *idxd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) for (i = 0; i < idxd->max_wqs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) struct idxd_wq *wq = &idxd->wqs[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) device_unregister(&wq->conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) for (i = 0; i < idxd->max_engines; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) struct idxd_engine *engine = &idxd->engines[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) device_unregister(&engine->conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) for (i = 0; i < idxd->max_groups; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) struct idxd_group *group = &idxd->groups[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) device_unregister(&group->conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) device_unregister(&idxd->conf_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) int idxd_register_bus_type(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) int i, rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) for (i = 0; i < IDXD_TYPE_MAX; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) rc = bus_register(idxd_bus_types[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) goto bus_err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) bus_err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) while (--i >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) bus_unregister(idxd_bus_types[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) void idxd_unregister_bus_type(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) for (i = 0; i < IDXD_TYPE_MAX; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) bus_unregister(idxd_bus_types[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) }