From patchwork Mon Feb 1 12:55:58 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Balasubramanian Manoharan X-Patchwork-Id: 60907 Delivered-To: patch@linaro.org Received: by 10.112.130.2 with SMTP id oa2csp3055258lbb; Mon, 1 Feb 2016 04:57:28 -0800 (PST) X-Received: by 10.107.32.2 with SMTP id g2mr21094902iog.39.1454331447943; Mon, 01 Feb 2016 04:57:27 -0800 (PST) Return-Path: Received: from lists.linaro.org (lists.linaro.org. [54.225.227.206]) by mx.google.com with ESMTP id l10si7396682iod.158.2016.02.01.04.57.27; Mon, 01 Feb 2016 04:57:27 -0800 (PST) Received-SPF: pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) client-ip=54.225.227.206; Authentication-Results: mx.google.com; spf=pass (google.com: domain of lng-odp-bounces@lists.linaro.org designates 54.225.227.206 as permitted sender) smtp.mailfrom=lng-odp-bounces@lists.linaro.org; dkim=neutral (body hash did not verify) header.i=@linaro.org Received: by lists.linaro.org (Postfix, from userid 109) id 1FE05616B0; Mon, 1 Feb 2016 12:57:27 +0000 (UTC) Authentication-Results: lists.linaro.org; dkim=fail reason="verification failed; unprotected key" header.d=linaro.org header.i=@linaro.org header.b=bpsG4yuZ; dkim-adsp=none (unprotected policy); dkim-atps=neutral X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on ip-10-142-244-252 X-Spam-Level: X-Spam-Status: No, score=-2.5 required=5.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_LOW,RCVD_IN_MSPIKE_H2,T_DKIM_INVALID,URIBL_BLOCKED autolearn=disabled version=3.4.0 Received: from [127.0.0.1] (localhost [127.0.0.1]) by lists.linaro.org (Postfix) with ESMTP id 6D32B616CC; Mon, 1 Feb 2016 12:56:46 +0000 (UTC) X-Original-To: lng-odp@lists.linaro.org Delivered-To: lng-odp@lists.linaro.org Received: by lists.linaro.org (Postfix, from userid 109) id ECFAE616ED; Mon, 1 Feb 2016 12:56:37 +0000 (UTC) Received: from mail-pf0-f179.google.com (mail-pf0-f179.google.com [209.85.192.179]) by lists.linaro.org (Postfix) with ESMTPS id 849086162B for ; Mon, 1 Feb 2016 12:56:26 +0000 (UTC) Received: by mail-pf0-f179.google.com with SMTP id n128so83014178pfn.3 for ; Mon, 01 Feb 2016 04:56:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=VyDOjb0qJdWRSvMnKXEiR5tE+ulZ60WdzXL8uymDNiU=; b=bpsG4yuZcZXYWGL6Lq9n0lFIdFRuTJFqiZzETdwk+63f7WuM1jK+dM3ykkBHRY9Y/c QnlkAD2BIypAMoR7S1N5VrElt4ZQXNjbIzGYuA8dkh74apUU9kIKHn+kIKDNbeVihsO6 CbRxClTS9AGo2iS/G8T7PdZ07GPW0cQ7kyoBQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=VyDOjb0qJdWRSvMnKXEiR5tE+ulZ60WdzXL8uymDNiU=; b=B2OJi6IbHHPim+5cdXBb5o2awBKzFunyxWZcnfkbwRfv0GUnEUnltRhzLX8iUCwIqS Ik+NdPVs6Z+J+uaHkSuzVzAbVckwsTqzyvXVCJmQRToHBf/+YSAYFQzW5pARH+9XmWEQ YT0KM3eB3h3Y9m3xZLB87Rw25YdvwcfLDNCqoKhfGnMxsZWUE48S3foOtUrYmouqAF6S T5gZ5jJ8G4oSyfsfoyZSwiD3cbuLxQ8vM7lQlWTcFGVtkrVnDDf/oISljfGpoOtKvFp9 OUXi2isLVMkmoelCAvr0Lpy/awa6WhNyEkSCVsHT0oz6OYT1dGMHXud+J8POprVo74j2 QsAg== X-Gm-Message-State: AG10YOT64pwE20thyYgz2DLeomDxvuGPtDHnbpx65d4HdMSnVz1jGA1ZxuRqSMQC8STZrXyPpqU= X-Received: by 10.98.19.205 with SMTP id 74mr36519738pft.31.1454331385920; Mon, 01 Feb 2016 04:56:25 -0800 (PST) Received: from localhost.localdomain ([122.166.219.57]) by smtp.gmail.com with ESMTPSA id y86sm43188805pfa.26.2016.02.01.04.56.23 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 01 Feb 2016 04:56:25 -0800 (PST) From: Balasubramanian Manoharan To: lng-odp@lists.linaro.org Date: Mon, 1 Feb 2016 18:25:58 +0530 Message-Id: <1454331360-16717-2-git-send-email-bala.manoharan@linaro.org> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1454331360-16717-1-git-send-email-bala.manoharan@linaro.org> References: <1454331360-16717-1-git-send-email-bala.manoharan@linaro.org> X-Topics: Classification patch Cc: petri.savolainen@nokia.com Subject: [lng-odp] [API-NEXT PATCHv2 2/4] linux-generic: classification: implement pmr create api X-BeenThere: lng-odp@lists.linaro.org X-Mailman-Version: 2.1.16 Precedence: list List-Id: "The OpenDataPlane \(ODP\) List" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: lng-odp-bounces@lists.linaro.org Sender: "lng-odp" Implements packet match rule create functions. If a packet match rule needs to be applied at the pktio level it has to be configured to the default class of service. Signed-off-by: Balasubramanian Manoharan --- .../include/odp_classification_datamodel.h | 48 +--- .../include/odp_classification_internal.h | 21 +- platform/linux-generic/odp_classification.c | 313 ++++++--------------- platform/linux-generic/odp_packet_io.c | 24 +- 4 files changed, 94 insertions(+), 312 deletions(-) diff --git a/platform/linux-generic/include/odp_classification_datamodel.h b/platform/linux-generic/include/odp_classification_datamodel.h index 27d8a52..6301f18 100644 --- a/platform/linux-generic/include/odp_classification_datamodel.h +++ b/platform/linux-generic/include/odp_classification_datamodel.h @@ -28,14 +28,12 @@ extern "C" { /* Maximum Class Of Service Entry */ #define ODP_COS_MAX_ENTRY 64 -/* Maximum PMR Set Entry */ -#define ODP_PMRSET_MAX_ENTRY 64 /* Maximum PMR Entry */ -#define ODP_PMR_MAX_ENTRY 64 +#define ODP_PMR_MAX_ENTRY 256 /* Maximum PMR Terms in a PMR Set */ #define ODP_PMRTERM_MAX 8 /* Maximum PMRs attached in PKTIO Level */ -#define ODP_PKTIO_MAX_PMR 8 +#define ODP_PMR_PER_COS_MAX 8 /* L2 Priority Bits */ #define ODP_COS_L2_QOS_BITS 3 /* Max L2 QoS value */ @@ -67,15 +65,16 @@ Class Of Service struct cos_s { queue_entry_t *queue; /* Associated Queue */ pool_entry_t *pool; /* Associated Buffer pool */ - union pmr_u *pmr; /* Chained PMR */ - union cos_u *linked_cos; /* CoS linked with the PMR */ + union pmr_u *pmr[ODP_PMR_PER_COS_MAX]; /* Chained PMR */ + union cos_u *linked_cos[ODP_PMR_PER_COS_MAX]; /* Chained CoS with PMR*/ uint32_t valid; /* validity Flag */ - odp_cls_drop_t drop_policy; /* Associated Drop Policy */ + odp_cls_drop_t drop_policy; /* Associated Drop Policy */ odp_queue_group_t queue_group; /* Associated Queue Group */ odp_cos_flow_set_t flow_set; /* Assigned Flow Set */ - char name[ODP_COS_NAME_LEN]; /* name */ size_t headroom; /* Headroom for this CoS */ odp_spinlock_t lock; /* cos lock */ + odp_atomic_u32_t num_rule; /* num of PMRs attached with this CoS */ + char name[ODP_COS_NAME_LEN]; /* name */ }; typedef union cos_u { @@ -93,7 +92,9 @@ struct pmr_s { odp_atomic_u32_t count; /* num of packets matching this rule */ uint32_t num_pmr; /* num of PMR Term Values*/ odp_spinlock_t lock; /* pmr lock*/ - pmr_term_value_t pmr_term_value[1]; /* Associated PMR Term */ + cos_t *src_cos; /* source CoS where PMR is attached */ + pmr_term_value_t pmr_term_value[ODP_PMRTERM_MAX]; + /* List of associated PMR Terms */ }; typedef union pmr_u { @@ -102,24 +103,6 @@ typedef union pmr_u { } pmr_t; /** -Packet Matching Rule Set - -This structure is implemented as a extension over struct pmr_s -In order to use same pointer to access both pmr_s and pmr_set_s -'num_pmr' value is used to differentiate between pmr_s and pmr_set_s struct -**/ -struct pmr_set_s { - pmr_t pmr; - pmr_term_value_t pmr_term_value[ODP_PMRTERM_MAX - 1]; - /* List of associated PMR Terms */ -}; - -typedef union pmr_set_u { - struct pmr_set_s s; - uint8_t pad[ODP_CACHE_LINE_SIZE_ROUNDUP(sizeof(struct pmr_set_s))]; -} pmr_set_t; - -/** L2 QoS and CoS Map This structure holds the mapping between L2 QoS value and @@ -148,10 +131,6 @@ This structure is stored in pktio_entry and holds all the classifier configuration value. **/ typedef struct classifier { - odp_spinlock_t lock; /*pktio_cos lock */ - uint32_t num_pmr; /* num of PMRs linked to given PKTIO*/ - pmr_t *pmr[ODP_PKTIO_MAX_PMR]; /* PMRs linked with this PKTIO */ - cos_t *cos[ODP_PKTIO_MAX_PMR]; /* CoS linked with this PKTIO */ cos_t *error_cos; /* Associated Error CoS */ cos_t *default_cos; /* Associated Default CoS */ uint32_t l3_precedence; /* L3 QoS precedence */ @@ -171,13 +150,6 @@ typedef struct odp_cos_table { } cos_tbl_t; /** -PMR set table -**/ -typedef struct pmr_set_tbl { - pmr_set_t pmr_set[ODP_PMRSET_MAX_ENTRY]; -} pmr_set_tbl_t; - -/** PMR table **/ typedef struct pmr_tbl { diff --git a/platform/linux-generic/include/odp_classification_internal.h b/platform/linux-generic/include/odp_classification_internal.h index 1e8f291..3fa18ad 100644 --- a/platform/linux-generic/include/odp_classification_internal.h +++ b/platform/linux-generic/include/odp_classification_internal.h @@ -117,12 +117,6 @@ int update_flow_signature(uint8_t *pkt_addr, cos_t *cos); /** @internal -Allocate a odp_pmr_set_t Handle -*/ -odp_pmr_set_t alloc_pmr_set(pmr_t **pmr); - -/** -@internal Allocate a odp_pmr_t Handle */ odp_pmr_t alloc_pmr(pmr_t **pmr); @@ -132,24 +126,11 @@ odp_pmr_t alloc_pmr(pmr_t **pmr); Pointer to pmr_set_t Handle This function checks for validity of pmr_set_t Handle */ -pmr_set_t *get_pmr_set_entry(odp_pmr_set_t pmr_set_id); - -/** -@internal -Pointer to pmr_set_t Handle -*/ -pmr_set_t *get_pmr_set_entry_internal(odp_pmr_set_t pmr_set_id); - -/** -@internal -Pointer to pmr_set_t Handle -This function checks for validity of pmr_set_t Handle -*/ pmr_t *get_pmr_entry(odp_pmr_t pmr_id); /** @internal -Pointer to pmr_set_t Handle +Pointer to pmr_t Handle */ pmr_t *get_pmr_entry_internal(odp_pmr_t pmr_id); diff --git a/platform/linux-generic/odp_classification.c b/platform/linux-generic/odp_classification.c index da195ad..88017ce 100644 --- a/platform/linux-generic/odp_classification.c +++ b/platform/linux-generic/odp_classification.c @@ -27,7 +27,6 @@ #define LOCK_INIT(a) odp_spinlock_init(a) static cos_tbl_t *cos_tbl; -static pmr_set_tbl_t *pmr_set_tbl; static pmr_tbl_t *pmr_tbl; cos_t *get_cos_entry_internal(odp_cos_t cos_id) @@ -35,11 +34,6 @@ cos_t *get_cos_entry_internal(odp_cos_t cos_id) return &(cos_tbl->cos_entry[_odp_typeval(cos_id)]); } -pmr_set_t *get_pmr_set_entry_internal(odp_pmr_set_t pmr_set_id) -{ - return &(pmr_set_tbl->pmr_set[_odp_typeval(pmr_set_id)]); -} - pmr_t *get_pmr_entry_internal(odp_pmr_t pmr_id) { return &(pmr_tbl->pmr[_odp_typeval(pmr_id)]); @@ -49,7 +43,6 @@ int odp_classification_init_global(void) { odp_shm_t cos_shm; odp_shm_t pmr_shm; - odp_shm_t pmr_set_shm; int i; cos_shm = odp_shm_reserve("shm_odp_cos_tbl", @@ -94,32 +87,8 @@ int odp_classification_init_global(void) LOCK_INIT(&pmr->s.lock); } - pmr_set_shm = odp_shm_reserve("shm_odp_pmr_set_tbl", - sizeof(pmr_set_tbl_t), - sizeof(pmr_set_t), 0); - - if (pmr_set_shm == ODP_SHM_INVALID) { - ODP_ERR("shm allocation failed for shm_odp_pmr_set_tbl"); - goto error_pmr; - } - - pmr_set_tbl = odp_shm_addr(pmr_set_shm); - if (pmr_set_tbl == NULL) - goto error_pmrset; - - memset(pmr_set_tbl, 0, sizeof(pmr_set_tbl_t)); - for (i = 0; i < ODP_PMRSET_MAX_ENTRY; i++) { - /* init locks */ - pmr_set_t *pmr = - get_pmr_set_entry_internal - (_odp_cast_scalar(odp_pmr_set_t, i)); - LOCK_INIT(&pmr->s.pmr.s.lock); - } - return 0; -error_pmrset: - odp_shm_free(pmr_set_shm); error_pmr: odp_shm_free(pmr_shm); error_cos: @@ -145,12 +114,6 @@ int odp_classification_term_global(void) rc = -1; } - ret = odp_shm_free(odp_shm_lookup("shm_odp_pmr_set_tbl")); - if (ret < 0) { - ODP_ERR("shm free failed for shm_odp_pmr_tbl"); - rc = -1; - } - return rc; } @@ -163,7 +126,7 @@ void odp_cls_cos_param_init(odp_cls_cos_param_t *param) odp_cos_t odp_cls_cos_create(const char *name, odp_cls_cos_param_t *param) { - int i; + int i, j; queue_entry_t *queue; pool_entry_t *pool; odp_cls_drop_t drop_policy; @@ -187,14 +150,18 @@ odp_cos_t odp_cls_cos_create(const char *name, odp_cls_cos_param_t *param) strncpy(cos_tbl->cos_entry[i].s.name, name, ODP_COS_NAME_LEN - 1); cos_tbl->cos_entry[i].s.name[ODP_COS_NAME_LEN - 1] = 0; - cos_tbl->cos_entry[i].s.pmr = NULL; - cos_tbl->cos_entry[i].s.linked_cos = NULL; + for (j = 0; j < ODP_PMR_PER_COS_MAX; j++) { + cos_tbl->cos_entry[i].s.pmr[j] = NULL; + cos_tbl->cos_entry[i].s.linked_cos[j] = NULL; + } cos_tbl->cos_entry[i].s.queue = queue; cos_tbl->cos_entry[i].s.pool = pool; cos_tbl->cos_entry[i].s.flow_set = 0; cos_tbl->cos_entry[i].s.headroom = 0; cos_tbl->cos_entry[i].s.valid = 1; cos_tbl->cos_entry[i].s.drop_policy = drop_policy; + odp_atomic_init_u32(&cos_tbl->cos_entry[i] + .s.num_rule, 0); UNLOCK(&cos_tbl->cos_entry[i].s.lock); return _odp_cast_scalar(odp_cos_t, i); } @@ -205,27 +172,6 @@ odp_cos_t odp_cls_cos_create(const char *name, odp_cls_cos_param_t *param) return ODP_COS_INVALID; } -odp_pmr_set_t alloc_pmr_set(pmr_t **pmr) -{ - int i; - - for (i = 0; i < ODP_PMRSET_MAX_ENTRY; i++) { - LOCK(&pmr_set_tbl->pmr_set[i].s.pmr.s.lock); - if (0 == pmr_set_tbl->pmr_set[i].s.pmr.s.valid) { - pmr_set_tbl->pmr_set[i].s.pmr.s.valid = 1; - pmr_set_tbl->pmr_set[i].s.pmr.s.num_pmr = 0; - *pmr = (pmr_t *)&pmr_set_tbl->pmr_set[i]; - odp_atomic_init_u32(&pmr_set_tbl->pmr_set[i] - .s.pmr.s.count, 0); - /* return as locked */ - return _odp_cast_scalar(odp_pmr_set_t, i); - } - UNLOCK(&pmr_set_tbl->pmr_set[i].s.pmr.s.lock); - } - ODP_ERR("ODP_PMRSET_MAX_ENTRY reached"); - return ODP_PMR_SET_INVAL; -} - odp_pmr_t alloc_pmr(pmr_t **pmr) { int i; @@ -257,17 +203,6 @@ cos_t *get_cos_entry(odp_cos_t cos_id) return &(cos_tbl->cos_entry[_odp_typeval(cos_id)]); } - -pmr_set_t *get_pmr_set_entry(odp_pmr_set_t pmr_set_id) -{ - if (_odp_typeval(pmr_set_id) >= ODP_PMRSET_MAX_ENTRY || - pmr_set_id == ODP_PMR_SET_INVAL) - return NULL; - if (pmr_set_tbl->pmr_set[_odp_typeval(pmr_set_id)].s.pmr.s.valid == 0) - return NULL; - return &(pmr_set_tbl->pmr_set[_odp_typeval(pmr_set_id)]); -} - pmr_t *get_pmr_entry(odp_pmr_t pmr_id) { if (_odp_typeval(pmr_id) >= ODP_PMR_MAX_ENTRY || @@ -487,95 +422,39 @@ static void odp_pmr_create_term(pmr_term_value_t *value, value->val &= value->mask; } -odp_pmr_t odp_pmr_create(const odp_pmr_match_t *match) +int odp_cls_pmr_destroy(odp_pmr_t pmr_id) { + cos_t *src_cos; + uint32_t loc; pmr_t *pmr; - odp_pmr_t id; - if (match->val_sz > ODP_PMR_TERM_BYTES_MAX) { - ODP_ERR("val_sz greater than max supported limit"); - return ODP_PMR_INVAL; - } - - id = alloc_pmr(&pmr); - /*if alloc_pmr() is successful it returns with lock acquired*/ - if (id == ODP_PMR_INVAL) - return ODP_PMR_INVAL; - - pmr->s.num_pmr = 1; - odp_pmr_create_term(&pmr->s.pmr_term_value[0], match); - UNLOCK(&pmr->s.lock); - return id; -} - -int odp_pmr_destroy(odp_pmr_t pmr_id) -{ - pmr_t *pmr = get_pmr_entry(pmr_id); - - if (pmr == NULL) - return -1; - pmr->s.valid = 0; - return 0; -} - -int odp_pktio_pmr_cos(odp_pmr_t pmr_id, - odp_pktio_t src_pktio, - odp_cos_t dst_cos) -{ - uint8_t num_pmr; - pktio_entry_t *pktio_entry; - pmr_t *pmr; - cos_t *cos; - - pktio_entry = get_pktio_entry(src_pktio); - if (pktio_entry == NULL) { - ODP_ERR("Invalid odp_pktio_t handle"); - return -1; - } + uint8_t i; pmr = get_pmr_entry(pmr_id); - if (pmr == NULL) { - ODP_ERR("Invalid odp_pmr_t handle"); - return -1; - } - - cos = get_cos_entry(dst_cos); - if (cos == NULL) { - ODP_ERR("Invalid odp_cos_t handle"); - return -1; - } - - LOCK(&pktio_entry->s.cls.lock); - num_pmr = pktio_entry->s.cls.num_pmr; - if (num_pmr >= ODP_PKTIO_MAX_PMR) { - ODP_ERR("ODP_PKTIO_MAX_PMR reached"); - UNLOCK(&pktio_entry->s.cls.lock); - return -1; - } - - pktio_entry->s.cls.pmr[num_pmr] = pmr; - pktio_entry->s.cls.cos[num_pmr] = cos; - pktio_entry->s.cls.num_pmr++; - pktio_cls_enabled_set(pktio_entry, 1); - UNLOCK(&pktio_entry->s.cls.lock); + if (pmr == NULL || pmr->s.src_cos == NULL) + return -1; + + src_cos = pmr->s.src_cos; + LOCK(&src_cos->s.lock); + loc = odp_atomic_load_u32(&src_cos->s.num_rule); + if (loc == 0) + goto no_rule; + loc -= 1; + for (i = 0; i <= loc; i++) + if (src_cos->s.pmr[i] == pmr) { + src_cos->s.pmr[i] = src_cos->s.pmr[loc]; + src_cos->s.linked_cos[i] = src_cos->s.linked_cos[loc]; + } + odp_atomic_dec_u32(&src_cos->s.num_rule); +no_rule: + pmr->s.valid = 0; + UNLOCK(&src_cos->s.lock); return 0; } -int odp_cos_pmr_cos(odp_pmr_t pmr_id, odp_cos_t src_cos, odp_cos_t dst_cos) +int odp_cls_pmr_num_terms(void) { - cos_t *cos_src = get_cos_entry(src_cos); - cos_t *cos_dst = get_cos_entry(dst_cos); - pmr_t *pmr = get_pmr_entry(pmr_id); - if (NULL == cos_src || NULL == cos_dst || NULL == pmr) { - ODP_ERR("Invalid input handle"); - return -1; - } - - /*Locking is not required as intermittent stale data is acceptable*/ - cos_src->s.pmr = pmr; - cos_src->s.linked_cos = cos_dst; - - return 0; + return ODP_PMRTERM_MAX; } unsigned long long odp_pmr_terms_cap(void) @@ -604,91 +483,53 @@ unsigned odp_pmr_terms_avail(void) return count; } -int odp_pmr_match_set_create(int num_terms, const odp_pmr_match_t *terms, - odp_pmr_set_t *pmr_set_id) +odp_pmr_t odp_cls_pmr_create(int num_terms, const odp_pmr_match_t *terms, + odp_cos_t src_cos, odp_cos_t dst_cos) { pmr_t *pmr; int i; - odp_pmr_set_t id; + odp_pmr_t id; int val_sz; - int count = 0; + uint32_t loc; + cos_t *cos_src = get_cos_entry(src_cos); + cos_t *cos_dst = get_cos_entry(dst_cos); + + if (NULL == cos_src || NULL == cos_dst) { + ODP_ERR("Invalid input handle"); + return ODP_PMR_INVAL; + } if (num_terms > ODP_PMRTERM_MAX) { ODP_ERR("no of terms greater than supported ODP_PMRTERM_MAX"); - return -1; + return ODP_PMR_INVAL; } - id = alloc_pmr_set(&pmr); - /*if alloc_pmr_set is successful it returns with the acquired lock*/ - if (id == ODP_PMR_SET_INVAL) { - *pmr_set_id = id; - return -1; - } + if (ODP_PMR_PER_COS_MAX == odp_atomic_load_u32(&cos_src->s.num_rule)) + return ODP_PMR_INVAL; + + id = alloc_pmr(&pmr); + /*if alloc_pmr is successful it returns with the acquired lock*/ + if (id == ODP_PMR_INVAL) + return id; pmr->s.num_pmr = num_terms; for (i = 0; i < num_terms; i++) { val_sz = terms[i].val_sz; - if (val_sz > ODP_PMR_TERM_BYTES_MAX) - continue; + if (val_sz > ODP_PMR_TERM_BYTES_MAX) { + pmr->s.valid = 0; + UNLOCK(&pmr->s.lock); + return ODP_PMR_INVAL; + } odp_pmr_create_term(&pmr->s.pmr_term_value[i], &terms[i]); - count++; - } - *pmr_set_id = id; - UNLOCK(&pmr->s.lock); - return count; -} - -int odp_pmr_match_set_destroy(odp_pmr_set_t pmr_set_id) -{ - pmr_set_t *pmr_set = get_pmr_set_entry(pmr_set_id); - if (pmr_set == NULL) - return -1; - - pmr_set->s.pmr.s.valid = 0; - return 0; -} - -int odp_pktio_pmr_match_set_cos(odp_pmr_set_t pmr_set_id, odp_pktio_t src_pktio, - odp_cos_t dst_cos) -{ - uint8_t num_pmr; - pktio_entry_t *pktio_entry; - pmr_t *pmr; - cos_t *cos; - - pktio_entry = get_pktio_entry(src_pktio); - if (pktio_entry == NULL) { - ODP_ERR("Invalid odp_pktio_t handle"); - return -1; } - pmr = (pmr_t *)get_pmr_set_entry(pmr_set_id); - if (pmr == NULL) { - ODP_ERR("Invalid odp_pmr_set_t handle"); - return -1; - } + loc = odp_atomic_fetch_inc_u32(&cos_src->s.num_rule); + cos_src->s.pmr[loc] = pmr; + cos_src->s.linked_cos[loc] = cos_dst; + pmr->s.src_cos = cos_src; - cos = get_cos_entry(dst_cos); - if (cos == NULL) { - ODP_ERR("Invalid odp_cos_t handle"); - return -1; - } - - LOCK(&pktio_entry->s.cls.lock); - num_pmr = pktio_entry->s.cls.num_pmr; - if (num_pmr >= ODP_PKTIO_MAX_PMR) { - ODP_ERR("ODP_PKTIO_MAX_PMR reached"); - UNLOCK(&pktio_entry->s.cls.lock); - return -1; - } - - pktio_entry->s.cls.pmr[num_pmr] = pmr; - pktio_entry->s.cls.cos[num_pmr] = cos; - pktio_entry->s.cls.num_pmr++; - pktio_cls_enabled_set(pktio_entry, 1); - UNLOCK(&pktio_entry->s.cls.lock); - - return 0; + UNLOCK(&pmr->s.lock); + return id; } int odp_cls_cos_pool_set(odp_cos_t cos_id, odp_pool_t pool_id) @@ -846,7 +687,10 @@ int verify_pmr(pmr_t *pmr, const uint8_t *pkt_addr, odp_packet_hdr_t *pkt_hdr) cos_t *match_pmr_cos(cos_t *cos, const uint8_t *pkt_addr, pmr_t *pmr, odp_packet_hdr_t *hdr) { - cos_t *retcos = NULL; + cos_t *retcos; + uint32_t i; + + retcos = NULL; if (cos == NULL || pmr == NULL) return NULL; @@ -857,10 +701,15 @@ cos_t *match_pmr_cos(cos_t *cos, const uint8_t *pkt_addr, pmr_t *pmr, if (verify_pmr(pmr, pkt_addr, hdr)) { /** This gets called recursively to check all the PMRs in * a PMR chain */ - retcos = match_pmr_cos(cos->s.linked_cos, pkt_addr, - cos->s.pmr, hdr); - if (!retcos) + if (0 == odp_atomic_load_u32(&cos->s.num_rule)) return cos; + + for (i = 0; i < odp_atomic_load_u32(&cos->s.num_rule); i++) { + retcos = match_pmr_cos(cos->s.linked_cos[i], pkt_addr, + cos->s.pmr[i], hdr); + if (!retcos) + return cos; + } } return retcos; } @@ -868,23 +717,17 @@ cos_t *match_pmr_cos(cos_t *cos, const uint8_t *pkt_addr, pmr_t *pmr, int pktio_classifier_init(pktio_entry_t *entry) { classifier_t *cls; - int i; + /* classifier lock should be acquired by the calling function */ if (entry == NULL) return -1; cls = &entry->s.cls; - cls->num_pmr = 0; cls->flow_set = 0; cls->error_cos = NULL; cls->default_cos = NULL; cls->headroom = 0; cls->skip = 0; - for (i = 0; i < ODP_PKTIO_MAX_PMR; i++) { - cls->pmr[i] = NULL; - cls->cos[i] = NULL; - } - return 0; } @@ -946,10 +789,12 @@ cos_t *pktio_select_cos(pktio_entry_t *entry, const uint8_t *pkt_addr, { pmr_t *pmr; cos_t *cos; + cos_t *default_cos; uint32_t i; classifier_t *cls; cls = &entry->s.cls; + default_cos = cls->default_cos; /* Check for lazy parse needed */ if (packet_parse_not_complete(pkt_hdr)) @@ -959,9 +804,9 @@ cos_t *pktio_select_cos(pktio_entry_t *entry, const uint8_t *pkt_addr, if (pkt_hdr->error_flags.all) return cls->error_cos; /* Calls all the PMRs attached at the PKTIO level*/ - for (i = 0; i < cls->num_pmr; i++) { - pmr = entry->s.cls.pmr[i]; - cos = entry->s.cls.cos[i]; + for (i = 0; i < odp_atomic_load_u32(&default_cos->s.num_rule); i++) { + pmr = default_cos->s.pmr[i]; + cos = default_cos->s.linked_cos[i]; cos = match_pmr_cos(cos, pkt_addr, pmr, pkt_hdr); if (cos) return cos; diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux-generic/odp_packet_io.c index b24cb1a..ed49198 100644 --- a/platform/linux-generic/odp_packet_io.c +++ b/platform/linux-generic/odp_packet_io.c @@ -57,7 +57,6 @@ int odp_pktio_init_global(void) odp_ticketlock_init(&pktio_entry->s.rxl); odp_ticketlock_init(&pktio_entry->s.txl); - odp_spinlock_init(&pktio_entry->s.cls.lock); odp_spinlock_init(&pktio_entry->s.cls.l2_cos_table.lock); odp_spinlock_init(&pktio_entry->s.cls.l3_cos_table.lock); @@ -117,20 +116,6 @@ static void unlock_entry(pktio_entry_t *entry) odp_ticketlock_unlock(&entry->s.rxl); } -static void lock_entry_classifier(pktio_entry_t *entry) -{ - odp_ticketlock_lock(&entry->s.rxl); - odp_ticketlock_lock(&entry->s.txl); - odp_spinlock_lock(&entry->s.cls.lock); -} - -static void unlock_entry_classifier(pktio_entry_t *entry) -{ - odp_spinlock_unlock(&entry->s.cls.lock); - odp_ticketlock_unlock(&entry->s.txl); - odp_ticketlock_unlock(&entry->s.rxl); -} - static void init_pktio_entry(pktio_entry_t *entry) { int i; @@ -156,13 +141,13 @@ static odp_pktio_t alloc_lock_pktio_entry(void) for (i = 0; i < ODP_CONFIG_PKTIO_ENTRIES; ++i) { entry = &pktio_tbl->entries[i]; if (is_free(entry)) { - lock_entry_classifier(entry); + lock_entry(entry); if (is_free(entry)) { init_pktio_entry(entry); id = _odp_cast_scalar(odp_pktio_t, i + 1); return id; /* return with entry locked! */ } - unlock_entry_classifier(entry); + unlock_entry(entry); } } @@ -201,8 +186,8 @@ static odp_pktio_t setup_pktio_entry(const char *dev, odp_pool_t pool, ODP_ERR("No resources available.\n"); return ODP_PKTIO_INVALID; } - /* if successful, alloc_pktio_entry() returns with the entry locked */ + /* if successful, alloc_pktio_entry() returns with the entry locked */ pktio_entry = get_pktio_entry(id); if (!pktio_entry) return ODP_PKTIO_INVALID; @@ -222,7 +207,6 @@ static odp_pktio_t setup_pktio_entry(const char *dev, odp_pool_t pool, } if (ret != 0) { - unlock_entry_classifier(pktio_entry); free_pktio_entry(id); id = ODP_PKTIO_INVALID; ODP_ERR("Unable to init any I/O type.\n"); @@ -230,10 +214,10 @@ static odp_pktio_t setup_pktio_entry(const char *dev, odp_pool_t pool, snprintf(pktio_entry->s.name, sizeof(pktio_entry->s.name), "%s", dev); pktio_entry->s.state = STATE_STOP; - unlock_entry_classifier(pktio_entry); } pktio_entry->s.handle = id; + unlock_entry(pktio_entry); return id; }