diff options
Diffstat (limited to 'platform/linux-generic/odp_classification.c')
-rw-r--r-- | platform/linux-generic/odp_classification.c | 119 |
1 files changed, 84 insertions, 35 deletions
diff --git a/platform/linux-generic/odp_classification.c b/platform/linux-generic/odp_classification.c index 3b50232d6..2fdecbc51 100644 --- a/platform/linux-generic/odp_classification.c +++ b/platform/linux-generic/odp_classification.c @@ -150,7 +150,7 @@ void odp_cls_pmr_param_init(odp_pmr_param_t *param) int odp_cls_capability(odp_cls_capability_t *capability) { - unsigned int count = 0; + uint32_t count = 0; memset(capability, 0, sizeof(odp_cls_capability_t)); @@ -161,6 +161,7 @@ int odp_cls_capability(odp_cls_capability_t *capability) capability->max_pmr_terms = CLS_PMR_MAX_ENTRY; capability->available_pmr_terms = count; capability->max_cos = CLS_COS_MAX_ENTRY; + capability->max_cos_stats = capability->max_cos; capability->pmr_range_supported = false; capability->supported_terms.all_bits = 0; capability->supported_terms.bit.len = 1; @@ -186,6 +187,8 @@ int odp_cls_capability(odp_cls_capability_t *capability) capability->threshold_bp.all_bits = 0; capability->max_hash_queues = CLS_COS_QUEUE_MAX; capability->max_mark = MAX_MARK; + capability->stats.cos.counter.discards = 1; + capability->stats.cos.counter.packets = 1; capability->stats.queue.counter.discards = 1; capability->stats.queue.counter.packets = 1; @@ -220,21 +223,29 @@ static inline void _cls_queue_unwind(uint32_t tbl_index, uint32_t j) odp_queue_destroy(queue_grp_tbl->s.queue[tbl_index + --j]); } -odp_cos_t odp_cls_cos_create(const char *name, const odp_cls_cos_param_t *param) +odp_cos_t odp_cls_cos_create(const char *name, const odp_cls_cos_param_t *param_in) { uint32_t i, j; odp_queue_t queue; odp_cls_drop_t drop_policy; cos_t *cos; uint32_t tbl_index; + odp_cls_cos_param_t param = *param_in; + + if (param.action == ODP_COS_ACTION_DROP) { + param.num_queue = 1; + param.queue = ODP_QUEUE_INVALID; + param.pool = ODP_POOL_INVALID; + param.vector.enable = false; + } /* num_queue should not be zero */ - if (param->num_queue > CLS_COS_QUEUE_MAX || param->num_queue < 1) + if (param.num_queue > CLS_COS_QUEUE_MAX || param.num_queue < 1) return ODP_COS_INVALID; /* Validate packet vector parameters */ - if (param->vector.enable) { - odp_pool_t pool = param->vector.pool; + if (param.vector.enable) { + odp_pool_t pool = param.vector.pool; odp_pool_info_t pool_info; if (pool == ODP_POOL_INVALID || odp_pool_info(pool, &pool_info)) { @@ -245,17 +256,17 @@ odp_cos_t odp_cls_cos_create(const char *name, const odp_cls_cos_param_t *param) ODP_ERR("wrong pool type\n"); return ODP_COS_INVALID; } - if (param->vector.max_size == 0) { + if (param.vector.max_size == 0) { ODP_ERR("vector.max_size is zero\n"); return ODP_COS_INVALID; } - if (param->vector.max_size > pool_info.params.vector.max_size) { + if (param.vector.max_size > pool_info.params.vector.max_size) { ODP_ERR("vector.max_size larger than pool max vector size\n"); return ODP_COS_INVALID; } } - drop_policy = param->drop_policy; + drop_policy = param.drop_policy; for (i = 0; i < CLS_COS_MAX_ENTRY; i++) { cos = &cos_tbl->cos_entry[i]; @@ -274,16 +285,16 @@ odp_cos_t odp_cls_cos_create(const char *name, const odp_cls_cos_param_t *param) cos->s.linked_cos[j] = NULL; } - cos->s.num_queue = param->num_queue; + cos->s.num_queue = param.num_queue; - if (param->num_queue > 1) { + if (param.num_queue > 1) { odp_queue_param_init(&cos->s.queue_param); cos->s.queue_group = true; cos->s.queue = ODP_QUEUE_INVALID; _odp_cls_update_hash_proto(cos, - param->hash_proto); + param.hash_proto); tbl_index = i * CLS_COS_QUEUE_MAX; - for (j = 0; j < param->num_queue; j++) { + for (j = 0; j < param.num_queue; j++) { queue = odp_queue_create(NULL, &cos->s.queue_param); if (queue == ODP_QUEUE_INVALID) { /* unwind the queues */ @@ -296,21 +307,27 @@ odp_cos_t odp_cls_cos_create(const char *name, const odp_cls_cos_param_t *param) } } else { - cos->s.queue = param->queue; + cos->s.queue = param.queue; } + + odp_atomic_init_u64(&cos->s.stats.discards, 0); + odp_atomic_init_u64(&cos->s.stats.packets, 0); + /* Initialize statistics counters */ for (j = 0; j < cos->s.num_queue; j++) { - odp_atomic_init_u64(&cos->s.stats[j].discards, 0); - odp_atomic_init_u64(&cos->s.stats[j].packets, 0); + odp_atomic_init_u64(&cos->s.queue_stats[j].discards, 0); + odp_atomic_init_u64(&cos->s.queue_stats[j].packets, 0); } - cos->s.pool = param->pool; + cos->s.action = param.action; + cos->s.pool = param.pool; cos->s.headroom = 0; cos->s.valid = 1; cos->s.drop_policy = drop_policy; odp_atomic_init_u32(&cos->s.num_rule, 0); cos->s.index = i; - cos->s.vector = param->vector; + cos->s.vector = param.vector; + cos->s.stats_enable = param.stats_enable; UNLOCK(&cos->s.lock); return _odp_cos_from_ndx(i); } @@ -1461,6 +1478,9 @@ static cos_t *match_pmr_cos(cos_t *cos, const uint8_t *pkt_addr, pmr_t *pmr, /* PMR matched */ pmr_debug_print(pmr, cos); + if (cos->s.stats_enable) + odp_atomic_inc_u64(&cos->s.stats.packets); + hdr->p.input_flags.cls_mark = 0; if (pmr->s.mark) { hdr->p.input_flags.cls_mark = 1; @@ -1537,8 +1557,11 @@ static inline cos_t *cls_select_cos(pktio_entry_t *entry, default_cos = cls->default_cos; /* Return error cos for error packet */ - if (pkt_hdr->p.flags.all.error) - return cls->error_cos; + if (pkt_hdr->p.flags.all.error) { + cos = cls->error_cos; + goto done; + } + /* Calls all the PMRs attached at the PKTIO level*/ for (i = 0; i < odp_atomic_load_u32(&default_cos->s.num_rule); i++) { pmr = default_cos->s.pmr[i]; @@ -1551,11 +1574,17 @@ static inline cos_t *cls_select_cos(pktio_entry_t *entry, cos = match_qos_cos(entry, pkt_addr, pkt_hdr); if (cos) { ODP_DBG_RAW(CLS_DBG, " QoS matched -> cos: %s(%u)\n", cos->s.name, cos->s.index); - return cos; + goto done; } ODP_DBG_RAW(CLS_DBG, " No match -> default cos\n"); - return cls->default_cos; + cos = cls->default_cos; + +done: + if (cos && cos->s.stats_enable) + odp_atomic_inc_u64(&cos->s.stats.packets); + + return cos; } static uint32_t packet_rss_hash(odp_packet_hdr_t *pkt_hdr, @@ -1575,12 +1604,12 @@ static uint32_t packet_rss_hash(odp_packet_hdr_t *pkt_hdr, * @retval 0 on success * @retval -EFAULT Bug * @retval -EINVAL Config error + * @retval -ENOENT Drop action * * @note *base is not released */ int _odp_cls_classify_packet(pktio_entry_t *entry, const uint8_t *base, - uint16_t pkt_len, uint32_t seg_len, odp_pool_t *pool, - odp_packet_hdr_t *pkt_hdr, odp_bool_t parse) + odp_pool_t *pool, odp_packet_hdr_t *pkt_hdr) { cos_t *cos; uint32_t tbl_index; @@ -1588,24 +1617,19 @@ int _odp_cls_classify_packet(pktio_entry_t *entry, const uint8_t *base, ODP_DBG_LVL(CLS_DBG, "Classify packet from %s\n", entry->s.full_name); - if (parse) { - packet_parse_reset(pkt_hdr, 1); - packet_set_len(pkt_hdr, pkt_len); - - _odp_packet_parse_common(&pkt_hdr->p, base, pkt_len, seg_len, - ODP_PROTO_LAYER_ALL, - entry->s.in_chksums); - } cos = cls_select_cos(entry, base, pkt_hdr); if (cos == NULL) return -EINVAL; + if (cos->s.action == ODP_COS_ACTION_DROP) + return -ENOENT; + if (cos->s.queue == ODP_QUEUE_INVALID && cos->s.num_queue == 1) - return -EFAULT; + goto error; if (cos->s.pool == ODP_POOL_INVALID) - return -EFAULT; + goto error; *pool = cos->s.pool; pkt_hdr->p.input_flags.dst_queue = 1; @@ -1623,6 +1647,10 @@ int _odp_cls_classify_packet(pktio_entry_t *entry, const uint8_t *base, cos->s.num_queue); pkt_hdr->dst_queue = queue_grp_tbl->s.queue[tbl_index]; return 0; + +error: + odp_atomic_inc_u64(&cos->s.stats.discards); + return -EFAULT; } static uint32_t packet_rss_hash(odp_packet_hdr_t *pkt_hdr, @@ -1780,6 +1808,27 @@ uint64_t odp_pmr_to_u64(odp_pmr_t hdl) return _odp_pri(hdl); } +int odp_cls_cos_stats(odp_cos_t hdl, odp_cls_cos_stats_t *stats) +{ + cos_t *cos = get_cos_entry(hdl); + + if (odp_unlikely(cos == NULL)) { + ODP_ERR("Invalid odp_cos_t handle\n"); + return -1; + } + + if (odp_unlikely(stats == NULL)) { + ODP_ERR("Output structure NULL\n"); + return -1; + } + + memset(stats, 0, sizeof(*stats)); + stats->discards = odp_atomic_load_u64(&cos->s.stats.discards); + stats->packets = odp_atomic_load_u64(&cos->s.stats.packets); + + return 0; +} + int odp_cls_queue_stats(odp_cos_t hdl, odp_queue_t queue, odp_cls_queue_stats_t *stats) { @@ -1803,8 +1852,8 @@ int odp_cls_queue_stats(odp_cos_t hdl, odp_queue_t queue, } memset(stats, 0, sizeof(odp_cls_queue_stats_t)); - stats->discards = odp_atomic_load_u64(&cos->s.stats[queue_idx].discards); - stats->packets = odp_atomic_load_u64(&cos->s.stats[queue_idx].packets); + stats->discards = odp_atomic_load_u64(&cos->s.queue_stats[queue_idx].discards); + stats->packets = odp_atomic_load_u64(&cos->s.queue_stats[queue_idx].packets); return 0; } |