-a 0002:0e:00.0,xae_cnt=16384
+- ``Event Group QoS support``
+
+ SSO GGRPs i.e. queue uses DRAM & SRAM buffers to hold in-flight
+ events. By default the buffers are assigned to the SSO GGRPs to
+ satisfy minimum HW requirements. SSO is free to assign the remaining
+ buffers to GGRPs based on a preconfigured threshold.
+ We can control the QoS of SSO GGRP by modifying the above mentioned
+ thresholds. GGRPs that have higher importance can be assigned higher
+ thresholds than the rest. The dictionary format is as follows
+ [Qx-XAQ-TAQ-IAQ][Qz-XAQ-TAQ-IAQ] expressed in percentages, 0 represents
+ default.
+
+ For example::
+
+ -a 0002:0e:00.0,qos=[1-50-50-50]
+
Debugging Options
-----------------
RTE_PMD_REGISTER_PCI(event_cn10k, cn10k_pci_sso);
RTE_PMD_REGISTER_PCI_TABLE(event_cn10k, cn10k_pci_sso_map);
RTE_PMD_REGISTER_KMOD_DEP(event_cn10k, "vfio-pci");
-RTE_PMD_REGISTER_PARAM_STRING(event_cn10k, CNXK_SSO_XAE_CNT "=<int>");
+RTE_PMD_REGISTER_PARAM_STRING(event_cn10k, CNXK_SSO_XAE_CNT "=<int>"
+ CNXK_SSO_GGRP_QOS "=<string>");
RTE_PMD_REGISTER_PCI(event_cn9k, cn9k_pci_sso);
RTE_PMD_REGISTER_PCI_TABLE(event_cn9k, cn9k_pci_sso_map);
RTE_PMD_REGISTER_KMOD_DEP(event_cn9k, "vfio-pci");
-RTE_PMD_REGISTER_PARAM_STRING(event_cn9k, CNXK_SSO_XAE_CNT "=<int>");
+RTE_PMD_REGISTER_PARAM_STRING(event_cn9k, CNXK_SSO_XAE_CNT "=<int>"
+ CNXK_SSO_GGRP_QOS "=<string>");
port_conf->enqueue_depth = 1;
}
+static void
+parse_queue_param(char *value, void *opaque)
+{
+ struct cnxk_sso_qos queue_qos = {0};
+ uint8_t *val = (uint8_t *)&queue_qos;
+ struct cnxk_sso_evdev *dev = opaque;
+ char *tok = strtok(value, "-");
+ struct cnxk_sso_qos *old_ptr;
+
+ if (!strlen(value))
+ return;
+
+ while (tok != NULL) {
+ *val = atoi(tok);
+ tok = strtok(NULL, "-");
+ val++;
+ }
+
+ if (val != (&queue_qos.iaq_prcnt + 1)) {
+ plt_err("Invalid QoS parameter expected [Qx-XAQ-TAQ-IAQ]");
+ return;
+ }
+
+ dev->qos_queue_cnt++;
+ old_ptr = dev->qos_parse_data;
+ dev->qos_parse_data = rte_realloc(
+ dev->qos_parse_data,
+ sizeof(struct cnxk_sso_qos) * dev->qos_queue_cnt, 0);
+ if (dev->qos_parse_data == NULL) {
+ dev->qos_parse_data = old_ptr;
+ dev->qos_queue_cnt--;
+ return;
+ }
+ dev->qos_parse_data[dev->qos_queue_cnt - 1] = queue_qos;
+}
+
+static void
+parse_qos_list(const char *value, void *opaque)
+{
+ char *s = strdup(value);
+ char *start = NULL;
+ char *end = NULL;
+ char *f = s;
+
+ while (*s) {
+ if (*s == '[')
+ start = s;
+ else if (*s == ']')
+ end = s;
+
+ if (start && start < end) {
+ *end = 0;
+ parse_queue_param(start + 1, opaque);
+ s = end;
+ start = end;
+ }
+ s++;
+ }
+
+ free(f);
+}
+
+static int
+parse_sso_kvargs_dict(const char *key, const char *value, void *opaque)
+{
+ RTE_SET_USED(key);
+
+ /* Dict format [Qx-XAQ-TAQ-IAQ][Qz-XAQ-TAQ-IAQ] use '-' cause ','
+ * isn't allowed. Everything is expressed in percentages, 0 represents
+ * default.
+ */
+ parse_qos_list(value, opaque);
+
+ return 0;
+}
+
static void
cnxk_sso_parse_devargs(struct cnxk_sso_evdev *dev, struct rte_devargs *devargs)
{
rte_kvargs_process(kvlist, CNXK_SSO_XAE_CNT, &parse_kvargs_value,
&dev->xae_cnt);
+ rte_kvargs_process(kvlist, CNXK_SSO_GGRP_QOS, &parse_sso_kvargs_dict,
+ dev);
rte_kvargs_free(kvlist);
}
#include "roc_api.h"
-#define CNXK_SSO_XAE_CNT "xae_cnt"
+#define CNXK_SSO_XAE_CNT "xae_cnt"
+#define CNXK_SSO_GGRP_QOS "qos"
#define USEC2NSEC(__us) ((__us)*1E3)
#define CNXK_SSO_XAQ_CACHE_CNT (0x7)
#define CNXK_SSO_XAQ_SLACK (8)
+struct cnxk_sso_qos {
+ uint16_t queue;
+ uint8_t xaq_prcnt;
+ uint8_t taq_prcnt;
+ uint8_t iaq_prcnt;
+};
+
struct cnxk_sso_evdev {
struct roc_sso sso;
uint8_t max_event_queues;
struct rte_mempool *xaq_pool;
/* Dev args */
uint32_t xae_cnt;
+ uint8_t qos_queue_cnt;
+ struct cnxk_sso_qos *qos_parse_data;
/* CN9K */
uint8_t dual_ws;
} __rte_cache_aligned;