/** * Initialize loopback * * Initialize ODP queues to create our own idea of loopbacks, which allow * testing without physical interfaces. Interface name string will be of * the format "loopX" where X is the decimal number of the interface. * * @param intf Loopback interface name string */ #if 0 /* Temporarely disable loopback mode. Needs packet output event queues */ static void initialize_loop(char *intf) { int idx; odp_queue_t outq_def; odp_queue_t inq_def; char queue_name[ODP_QUEUE_NAME_LEN]; odp_queue_param_t qparam; uint8_t *mac; char mac_str[MAX_STRING]; /* Derive loopback interface index */ idx = loop_if_index(intf); if (idx < 0) { EXAMPLE_ERR("Error: loopback \"%s\" invalid\n", intf); exit(EXIT_FAILURE); } /* Create input queue */ odp_queue_param_init(&qparam); qparam.type = ODP_QUEUE_TYPE_SCHED; qparam.sched.prio = ODP_SCHED_PRIO_DEFAULT; qparam.sched.sync = ODP_SCHED_SYNC_ATOMIC; qparam.sched.group = ODP_SCHED_GROUP_ALL; snprintf(queue_name, sizeof(queue_name), "%i-loop_inq_def", idx); queue_name[ODP_QUEUE_NAME_LEN - 1] = '\0'; inq_def = queue_create(queue_name, &qparam); if (ODP_QUEUE_INVALID == inq_def) { EXAMPLE_ERR("Error: input queue creation failed for %s\n", intf); exit(EXIT_FAILURE); } /* Create output queue */ snprintf(queue_name, sizeof(queue_name), "%i-loop_outq_def", idx); queue_name[ODP_QUEUE_NAME_LEN - 1] = '\0'; outq_def = queue_create(queue_name, NULL); if (ODP_QUEUE_INVALID == outq_def) { EXAMPLE_ERR("Error: output queue creation failed for %s\n", intf); exit(EXIT_FAILURE); } /* Initialize the loopback DB entry */ create_loopback_db_entry(idx, inq_def, outq_def, pkt_pool); mac = query_loopback_db_mac(idx); printf("Created loop:%02i, queue mode (ATOMIC queues)\n" " default loop%02i-INPUT queue:%" PRIu64 "\n" " default loop%02i-OUTPUT queue:%" PRIu64 "\n" " source mac address %s\n", idx, idx, odp_queue_to_u64(inq_def), idx, odp_queue_to_u64(outq_def), mac_addr_str(mac_str, mac)); /* Resolve any routes using this interface for output */ resolve_fwd_db(intf, outq_def, mac); }
/** * odp_queue_create wrapper to enable polling versus scheduling */ static odp_queue_t polled_odp_queue_create(const char *name, const odp_queue_param_t *param) { odp_queue_t my_queue; odp_queue_param_t qp; odp_queue_type_t type; odp_queue_param_init(&qp); if (param) memcpy(&qp, param, sizeof(odp_queue_param_t)); type = qp.type; if (ODP_QUEUE_TYPE_SCHED == type) { printf("%s: change %s to PLAIN\n", __func__, name); qp.type = ODP_QUEUE_TYPE_PLAIN; } my_queue = odp_queue_create(name, &qp); if (ODP_QUEUE_TYPE_SCHED == type) { poll_queues[num_polled_queues++] = my_queue; printf("%s: adding %"PRIu64"\n", __func__, odp_queue_to_u64(my_queue)); } return my_queue; }
/** * Create a pktio object * * @param dev Name of device to open * @param pool Pool to associate with device for packet RX/TX * * @return The handle of the created pktio object. * @warning This routine aborts if the create is unsuccessful. */ static odp_pktio_t create_pktio(const char *dev, odp_pool_t pool) { odp_queue_param_t qparam; char inq_name[ODP_QUEUE_NAME_LEN]; odp_pktio_t pktio; int ret; odp_queue_t inq_def; odp_pktio_param_t pktio_param; odp_pktio_param_init(&pktio_param); pktio_param.in_mode = ODP_PKTIN_MODE_DISABLED; /* Open a packet IO instance */ pktio = odp_pktio_open(dev, pool, &pktio_param); if (pktio == ODP_PKTIO_INVALID) EXAMPLE_ABORT("Error: pktio create failed for %s\n", dev); /* * Create and set the default INPUT queue associated with the 'pktio' * resource */ odp_queue_param_init(&qparam); qparam.sched.prio = ODP_SCHED_PRIO_DEFAULT; qparam.sched.sync = ODP_SCHED_SYNC_ATOMIC; qparam.sched.group = ODP_SCHED_GROUP_ALL; snprintf(inq_name, sizeof(inq_name), "%" PRIu64 "-pktio_inq_def", odp_pktio_to_u64(pktio)); inq_name[ODP_QUEUE_NAME_LEN - 1] = '\0'; inq_def = odp_queue_create(inq_name, ODP_QUEUE_TYPE_PKTIN, &qparam); if (inq_def == ODP_QUEUE_INVALID) EXAMPLE_ABORT("Error: pktio inq create failed for %s\n", dev); ret = odp_pktio_inq_setdef(pktio, inq_def); if (ret != 0) EXAMPLE_ABORT("Error: default input-Q setup for %s\n", dev); ret = odp_pktio_start(pktio); if (ret) EXAMPLE_ABORT("Error: unable to start %s\n", dev); printf(" created pktio:%02" PRIu64 ", dev:%s, queue mode (ATOMIC queues)\n" " default pktio%02" PRIu64 "-INPUT queue:%" PRIu64 "\n", odp_pktio_to_u64(pktio), dev, odp_pktio_to_u64(pktio), odp_queue_to_u64(inq_def)); return pktio; }
/** * Initialize interface * * Initialize ODP pktio and queues, query MAC address and update * forwarding database. * * @param intf Interface name string */ static void initialize_intf(char *intf) { odp_pktio_t pktio; odp_pktout_queue_t pktout; odp_queue_t inq; int ret; uint8_t src_mac[ODPH_ETHADDR_LEN]; char src_mac_str[MAX_STRING]; odp_pktio_param_t pktio_param; odp_pktin_queue_param_t pktin_param; odp_pktio_param_init(&pktio_param); if (getenv("ODP_IPSEC_USE_POLL_QUEUES")) pktio_param.in_mode = ODP_PKTIN_MODE_QUEUE; else pktio_param.in_mode = ODP_PKTIN_MODE_SCHED; /* * Open a packet IO instance for thread and get default output queue */ pktio = odp_pktio_open(intf, pkt_pool, &pktio_param); if (ODP_PKTIO_INVALID == pktio) { EXAMPLE_ERR("Error: pktio create failed for %s\n", intf); exit(EXIT_FAILURE); } odp_pktin_queue_param_init(&pktin_param); pktin_param.queue_param.sched.sync = ODP_SCHED_SYNC_ATOMIC; if (odp_pktin_queue_config(pktio, &pktin_param)) { EXAMPLE_ERR("Error: pktin config failed for %s\n", intf); exit(EXIT_FAILURE); } if (odp_pktout_queue_config(pktio, NULL)) { EXAMPLE_ERR("Error: pktout config failed for %s\n", intf); exit(EXIT_FAILURE); } if (odp_pktin_event_queue(pktio, &inq, 1) != 1) { EXAMPLE_ERR("Error: failed to get input queue for %s\n", intf); exit(EXIT_FAILURE); } if (odp_pktout_queue(pktio, &pktout, 1) != 1) { EXAMPLE_ERR("Error: failed to get pktout queue for %s\n", intf); exit(EXIT_FAILURE); } ret = odp_pktio_start(pktio); if (ret) { EXAMPLE_ERR("Error: unable to start %s\n", intf); exit(EXIT_FAILURE); } /* Read the source MAC address for this interface */ ret = odp_pktio_mac_addr(pktio, src_mac, sizeof(src_mac)); if (ret <= 0) { EXAMPLE_ERR("Error: failed during MAC address get for %s\n", intf); exit(EXIT_FAILURE); } printf("Created pktio:%02" PRIu64 ", queue mode (ATOMIC queues)\n" " default pktio%02" PRIu64 "-INPUT queue:%" PRIu64 "\n" " source mac address %s\n", odp_pktio_to_u64(pktio), odp_pktio_to_u64(pktio), odp_queue_to_u64(inq), mac_addr_str(src_mac_str, src_mac)); /* Resolve any routes using this interface for output */ resolve_fwd_db(intf, pktout, src_mac); }
/** * Initialize interface * * Initialize ODP pktio and queues, query MAC address and update * forwarding database. * * @param intf Interface name string */ static void initialize_intf(char *intf) { odp_pktio_t pktio; odp_queue_t outq_def; odp_queue_t inq_def; char inq_name[ODP_QUEUE_NAME_LEN]; odp_queue_param_t qparam; int ret; uint8_t src_mac[ODPH_ETHADDR_LEN]; char src_mac_str[MAX_STRING]; odp_pktio_param_t pktio_param; odp_pktio_param_init(&pktio_param); if (getenv("ODP_IPSEC_USE_POLL_QUEUES")) pktio_param.in_mode = ODP_PKTIN_MODE_QUEUE; else pktio_param.in_mode = ODP_PKTIN_MODE_SCHED; /* * Open a packet IO instance for thread and get default output queue */ pktio = odp_pktio_open(intf, pkt_pool, &pktio_param); if (ODP_PKTIO_INVALID == pktio) { EXAMPLE_ERR("Error: pktio create failed for %s\n", intf); exit(EXIT_FAILURE); } outq_def = odp_pktio_outq_getdef(pktio); /* * Create and set the default INPUT queue associated with the 'pktio' * resource */ odp_queue_param_init(&qparam); qparam.type = ODP_QUEUE_TYPE_PKTIN; qparam.sched.prio = ODP_SCHED_PRIO_DEFAULT; qparam.sched.sync = ODP_SCHED_SYNC_ATOMIC; qparam.sched.group = ODP_SCHED_GROUP_ALL; snprintf(inq_name, sizeof(inq_name), "%" PRIu64 "-pktio_inq_def", odp_pktio_to_u64(pktio)); inq_name[ODP_QUEUE_NAME_LEN - 1] = '\0'; inq_def = queue_create(inq_name, &qparam); if (ODP_QUEUE_INVALID == inq_def) { EXAMPLE_ERR("Error: pktio queue creation failed for %s\n", intf); exit(EXIT_FAILURE); } ret = odp_pktio_inq_setdef(pktio, inq_def); if (ret) { EXAMPLE_ERR("Error: default input-Q setup for %s\n", intf); exit(EXIT_FAILURE); } ret = odp_pktio_start(pktio); if (ret) { EXAMPLE_ERR("Error: unable to start %s\n", intf); exit(EXIT_FAILURE); } /* Read the source MAC address for this interface */ ret = odp_pktio_mac_addr(pktio, src_mac, sizeof(src_mac)); if (ret <= 0) { EXAMPLE_ERR("Error: failed during MAC address get for %s\n", intf); exit(EXIT_FAILURE); } printf("Created pktio:%02" PRIu64 ", queue mode (ATOMIC queues)\n" " default pktio%02" PRIu64 "-INPUT queue:%" PRIu64 "\n" " source mac address %s\n", odp_pktio_to_u64(pktio), odp_pktio_to_u64(pktio), odp_queue_to_u64(inq_def), mac_addr_str(src_mac_str, src_mac)); /* Resolve any routes using this interface for output */ resolve_fwd_db(intf, outq_def, src_mac); }
static int create_queues(void) { int i, j, prios, rc; odp_queue_capability_t capa; odp_pool_param_t params; odp_buffer_t queue_ctx_buf; queue_context *qctx, *pqctx; uint32_t ndx; odp_queue_param_t p; if (odp_queue_capability(&capa) < 0) { printf("Queue capability query failed\n"); return -1; } /* Limit to test maximum */ if (capa.max_ordered_locks > MAX_ORDERED_LOCKS) { capa.max_ordered_locks = MAX_ORDERED_LOCKS; printf("Testing only %u ordered locks\n", capa.max_ordered_locks); } prios = odp_schedule_num_prio(); odp_pool_param_init(¶ms); params.buf.size = sizeof(queue_context); params.buf.num = prios * QUEUES_PER_PRIO * 2; params.type = ODP_POOL_BUFFER; queue_ctx_pool = odp_pool_create(QUEUE_CTX_POOL_NAME, ¶ms); if (queue_ctx_pool == ODP_POOL_INVALID) { printf("Pool creation failed (queue ctx).\n"); return -1; } for (i = 0; i < prios; i++) { odp_queue_param_init(&p); p.type = ODP_QUEUE_TYPE_SCHED; p.sched.prio = i; for (j = 0; j < QUEUES_PER_PRIO; j++) { /* Per sched sync type */ char name[32]; odp_queue_t q, pq; snprintf(name, sizeof(name), "sched_%d_%d_n", i, j); p.sched.sync = ODP_SCHED_SYNC_PARALLEL; q = odp_queue_create(name, &p); if (q == ODP_QUEUE_INVALID) { printf("Schedule queue create failed.\n"); return -1; } snprintf(name, sizeof(name), "sched_%d_%d_a", i, j); p.sched.sync = ODP_SCHED_SYNC_ATOMIC; q = odp_queue_create(name, &p); if (q == ODP_QUEUE_INVALID) { printf("Schedule queue create failed.\n"); return -1; } snprintf(name, sizeof(name), "plain_%d_%d_o", i, j); pq = odp_queue_create(name, NULL); if (pq == ODP_QUEUE_INVALID) { printf("Plain queue create failed.\n"); return -1; } queue_ctx_buf = odp_buffer_alloc(queue_ctx_pool); if (queue_ctx_buf == ODP_BUFFER_INVALID) { printf("Cannot allocate plain queue ctx buf\n"); return -1; } pqctx = odp_buffer_addr(queue_ctx_buf); pqctx->ctx_handle = queue_ctx_buf; pqctx->sequence = 0; rc = odp_queue_context_set(pq, pqctx, 0); if (rc != 0) { printf("Cannot set plain queue context\n"); return -1; } snprintf(name, sizeof(name), "sched_%d_%d_o", i, j); p.sched.sync = ODP_SCHED_SYNC_ORDERED; p.sched.lock_count = capa.max_ordered_locks; q = odp_queue_create(name, &p); if (q == ODP_QUEUE_INVALID) { printf("Schedule queue create failed.\n"); return -1; } if (odp_queue_lock_count(q) != (int)capa.max_ordered_locks) { printf("Queue %" PRIu64 " created with " "%d locks instead of expected %d\n", odp_queue_to_u64(q), odp_queue_lock_count(q), capa.max_ordered_locks); return -1; } queue_ctx_buf = odp_buffer_alloc(queue_ctx_pool); if (queue_ctx_buf == ODP_BUFFER_INVALID) { printf("Cannot allocate queue ctx buf\n"); return -1; } qctx = odp_buffer_addr(queue_ctx_buf); qctx->ctx_handle = queue_ctx_buf; qctx->pq_handle = pq; qctx->sequence = 0; for (ndx = 0; ndx < capa.max_ordered_locks; ndx++) { qctx->lock_sequence[ndx] = 0; } rc = odp_queue_context_set(q, qctx, 0); if (rc != 0) { printf("Cannot set queue context\n"); return -1; } } } return 0; }
void queue_test_param(void) { odp_queue_t queue; odp_event_t enev[MAX_BUFFER_QUEUE]; odp_event_t deev[MAX_BUFFER_QUEUE]; odp_buffer_t buf; odp_event_t ev; odp_pool_t msg_pool; odp_event_t *pev_tmp; int i, deq_ret, ret; int nr_deq_entries = 0; int max_iteration = CONFIG_MAX_ITERATION; odp_queue_param_t qparams; odp_buffer_t enbuf; /* Schedule type queue */ odp_queue_param_init(&qparams); qparams.type = ODP_QUEUE_TYPE_SCHED; qparams.sched.prio = ODP_SCHED_PRIO_LOWEST; qparams.sched.sync = ODP_SCHED_SYNC_PARALLEL; qparams.sched.group = ODP_SCHED_GROUP_WORKER; queue = odp_queue_create("test_queue", &qparams); CU_ASSERT(ODP_QUEUE_INVALID != queue); CU_ASSERT(odp_queue_to_u64(queue) != odp_queue_to_u64(ODP_QUEUE_INVALID)); CU_ASSERT(queue == odp_queue_lookup("test_queue")); CU_ASSERT(ODP_QUEUE_TYPE_SCHED == odp_queue_type(queue)); CU_ASSERT(ODP_SCHED_PRIO_LOWEST == odp_queue_sched_prio(queue)); CU_ASSERT(ODP_SCHED_SYNC_PARALLEL == odp_queue_sched_type(queue)); CU_ASSERT(ODP_SCHED_GROUP_WORKER == odp_queue_sched_group(queue)); CU_ASSERT(0 == odp_queue_context_set(queue, &queue_context, sizeof(queue_context))); CU_ASSERT(&queue_context == odp_queue_context(queue)); CU_ASSERT(odp_queue_destroy(queue) == 0); /* Plain type queue */ odp_queue_param_init(&qparams); qparams.type = ODP_QUEUE_TYPE_PLAIN; qparams.context = &queue_context; qparams.context_len = sizeof(queue_context); queue = odp_queue_create("test_queue", &qparams); CU_ASSERT(ODP_QUEUE_INVALID != queue); CU_ASSERT(queue == odp_queue_lookup("test_queue")); CU_ASSERT(ODP_QUEUE_TYPE_PLAIN == odp_queue_type(queue)); CU_ASSERT(&queue_context == odp_queue_context(queue)); msg_pool = odp_pool_lookup("msg_pool"); buf = odp_buffer_alloc(msg_pool); CU_ASSERT_FATAL(buf != ODP_BUFFER_INVALID); ev = odp_buffer_to_event(buf); if (!(CU_ASSERT(odp_queue_enq(queue, ev) == 0))) { odp_buffer_free(buf); } else { CU_ASSERT(ev == odp_queue_deq(queue)); odp_buffer_free(buf); } for (i = 0; i < MAX_BUFFER_QUEUE; i++) { buf = odp_buffer_alloc(msg_pool); enev[i] = odp_buffer_to_event(buf); } /* * odp_queue_enq_multi may return 0..n buffers due to the resource * constraints in the implementation at that given point of time. * But here we assume that we succeed in enqueuing all buffers. */ ret = odp_queue_enq_multi(queue, enev, MAX_BUFFER_QUEUE); CU_ASSERT(MAX_BUFFER_QUEUE == ret); i = ret < 0 ? 0 : ret; for ( ; i < MAX_BUFFER_QUEUE; i++) odp_event_free(enev[i]); pev_tmp = deev; do { deq_ret = odp_queue_deq_multi(queue, pev_tmp, MAX_BUFFER_QUEUE); nr_deq_entries += deq_ret; max_iteration--; pev_tmp += deq_ret; CU_ASSERT(max_iteration >= 0); } while (nr_deq_entries < MAX_BUFFER_QUEUE); for (i = 0; i < MAX_BUFFER_QUEUE; i++) { enbuf = odp_buffer_from_event(enev[i]); CU_ASSERT(enev[i] == deev[i]); odp_buffer_free(enbuf); } CU_ASSERT(odp_queue_destroy(queue) == 0); }