X-Git-Url: http://git.droids-corp.org/?a=blobdiff_plain;f=app%2Ftest-pmd%2Fconfig.c;h=cc8e7aa13822efbdb66856fa7c41e1c6ee3909f8;hb=d906fff51878cf8dedb7f6f0aa24564d4f6d3597;hp=9ffb7d88dc0339d49ea11e4b1d6c638ba16f082c;hpb=9cbbee1451cbb13caca1d846d119cf28b3660c7a;p=dpdk.git diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c index 9ffb7d88dc..cc8e7aa138 100644 --- a/app/test-pmd/config.c +++ b/app/test-pmd/config.c @@ -2469,14 +2469,12 @@ port_queue_flow_create(portid_t port_id, queueid_t queue_id, const struct rte_flow_action *actions) { struct rte_flow_op_attr op_attr = { .postpone = postpone }; - struct rte_flow_op_result comp = { 0 }; struct rte_flow *flow; struct rte_port *port; struct port_flow *pf; struct port_table *pt; uint32_t id = 0; bool found; - int ret = 0; struct rte_flow_error error = { RTE_FLOW_ERROR_TYPE_NONE, NULL, NULL }; struct rte_flow_action_age *age = age_action_get(actions); @@ -2539,16 +2537,6 @@ port_queue_flow_create(portid_t port_id, queueid_t queue_id, return port_flow_complain(&error); } - while (ret == 0) { - /* Poisoning to make sure PMDs update it in case of error. */ - memset(&error, 0x22, sizeof(error)); - ret = rte_flow_pull(port_id, queue_id, &comp, 1, &error); - if (ret < 0) { - printf("Failed to pull queue\n"); - return -EINVAL; - } - } - pf->next = port->flow_list; pf->id = id; pf->flow = flow; @@ -2563,7 +2551,6 @@ port_queue_flow_destroy(portid_t port_id, queueid_t queue_id, bool postpone, uint32_t n, const uint32_t *rule) { struct rte_flow_op_attr op_attr = { .postpone = postpone }; - struct rte_flow_op_result comp = { 0 }; struct rte_port *port; struct port_flow **tmp; uint32_t c = 0; @@ -2599,21 +2586,6 @@ port_queue_flow_destroy(portid_t port_id, queueid_t queue_id, ret = port_flow_complain(&error); continue; } - - while (ret == 0) { - /* - * Poisoning to make sure PMD - * update it in case of error. - */ - memset(&error, 0x44, sizeof(error)); - ret = rte_flow_pull(port_id, queue_id, - &comp, 1, &error); - if (ret < 0) { - printf("Failed to pull queue\n"); - return -EINVAL; - } - } - printf("Flow rule #%u destruction enqueued\n", pf->id); *tmp = pf->next; free(pf); @@ -2626,6 +2598,137 @@ port_queue_flow_destroy(portid_t port_id, queueid_t queue_id, return ret; } +/** Enqueue indirect action create operation. */ +int +port_queue_action_handle_create(portid_t port_id, uint32_t queue_id, + bool postpone, uint32_t id, + const struct rte_flow_indir_action_conf *conf, + const struct rte_flow_action *action) +{ + const struct rte_flow_op_attr attr = { .postpone = postpone}; + struct rte_port *port; + struct port_indirect_action *pia; + int ret; + struct rte_flow_error error; + + ret = action_alloc(port_id, id, &pia); + if (ret) + return ret; + + port = &ports[port_id]; + if (queue_id >= port->queue_nb) { + printf("Queue #%u is invalid\n", queue_id); + return -EINVAL; + } + + if (action->type == RTE_FLOW_ACTION_TYPE_AGE) { + struct rte_flow_action_age *age = + (struct rte_flow_action_age *)(uintptr_t)(action->conf); + + pia->age_type = ACTION_AGE_CONTEXT_TYPE_INDIRECT_ACTION; + age->context = &pia->age_type; + } + /* Poisoning to make sure PMDs update it in case of error. */ + memset(&error, 0x88, sizeof(error)); + pia->handle = rte_flow_async_action_handle_create(port_id, queue_id, + &attr, conf, action, NULL, &error); + if (!pia->handle) { + uint32_t destroy_id = pia->id; + port_queue_action_handle_destroy(port_id, queue_id, + postpone, 1, &destroy_id); + return port_flow_complain(&error); + } + pia->type = action->type; + printf("Indirect action #%u creation queued\n", pia->id); + return 0; +} + +/** Enqueue indirect action destroy operation. */ +int +port_queue_action_handle_destroy(portid_t port_id, + uint32_t queue_id, bool postpone, + uint32_t n, const uint32_t *actions) +{ + const struct rte_flow_op_attr attr = { .postpone = postpone}; + struct rte_port *port; + struct port_indirect_action **tmp; + uint32_t c = 0; + int ret = 0; + + if (port_id_is_invalid(port_id, ENABLED_WARN) || + port_id == (portid_t)RTE_PORT_ALL) + return -EINVAL; + port = &ports[port_id]; + + if (queue_id >= port->queue_nb) { + printf("Queue #%u is invalid\n", queue_id); + return -EINVAL; + } + + tmp = &port->actions_list; + while (*tmp) { + uint32_t i; + + for (i = 0; i != n; ++i) { + struct rte_flow_error error; + struct port_indirect_action *pia = *tmp; + + if (actions[i] != pia->id) + continue; + /* + * Poisoning to make sure PMDs update it in case + * of error. + */ + memset(&error, 0x99, sizeof(error)); + + if (pia->handle && + rte_flow_async_action_handle_destroy(port_id, + queue_id, &attr, pia->handle, NULL, &error)) { + ret = port_flow_complain(&error); + continue; + } + *tmp = pia->next; + printf("Indirect action #%u destruction queued\n", + pia->id); + free(pia); + break; + } + if (i == n) + tmp = &(*tmp)->next; + ++c; + } + return ret; +} + +/** Enqueue indirect action update operation. */ +int +port_queue_action_handle_update(portid_t port_id, + uint32_t queue_id, bool postpone, uint32_t id, + const struct rte_flow_action *action) +{ + const struct rte_flow_op_attr attr = { .postpone = postpone}; + struct rte_port *port; + struct rte_flow_error error; + struct rte_flow_action_handle *action_handle; + + action_handle = port_action_handle_get_by_id(port_id, id); + if (!action_handle) + return -EINVAL; + + port = &ports[port_id]; + if (queue_id >= port->queue_nb) { + printf("Queue #%u is invalid\n", queue_id); + return -EINVAL; + } + + if (rte_flow_async_action_handle_update(port_id, queue_id, &attr, + action_handle, action, NULL, &error)) { + return port_flow_complain(&error); + } + printf("Indirect action #%u update queued\n", id); + return 0; +} + /** Push all the queue operations in the queue to the NIC. */ int port_queue_flow_push(portid_t port_id, queueid_t queue_id) @@ -2654,6 +2757,52 @@ port_queue_flow_push(portid_t port_id, queueid_t queue_id) return ret; } +/** Pull queue operation results from the queue. */ +int +port_queue_flow_pull(portid_t port_id, queueid_t queue_id) +{ + struct rte_port *port; + struct rte_flow_op_result *res; + struct rte_flow_error error; + int ret = 0; + int success = 0; + int i; + + if (port_id_is_invalid(port_id, ENABLED_WARN) || + port_id == (portid_t)RTE_PORT_ALL) + return -EINVAL; + port = &ports[port_id]; + + if (queue_id >= port->queue_nb) { + printf("Queue #%u is invalid\n", queue_id); + return -EINVAL; + } + + res = calloc(port->queue_sz, sizeof(struct rte_flow_op_result)); + if (!res) { + printf("Failed to allocate memory for pulled results\n"); + return -ENOMEM; + } + + memset(&error, 0x66, sizeof(error)); + ret = rte_flow_pull(port_id, queue_id, res, + port->queue_sz, &error); + if (ret < 0) { + printf("Failed to pull a operation results\n"); + free(res); + return -EINVAL; + } + + for (i = 0; i < ret; i++) { + if (res[i].status == RTE_FLOW_OP_SUCCESS) + success++; + } + printf("Queue #%u pulled %u operations (%u failed, %u succeeded)\n", + queue_id, ret, ret - success, success); + free(res); + return ret; +} + /** Create flow rule. */ int port_flow_create(portid_t port_id,