diff options
author | Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org> | 2016-01-11 21:39:58 +0200 |
---|---|---|
committer | Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org> | 2016-01-12 19:33:06 +0200 |
commit | 38d0735e8df45908766c86d244bd1f4f2b9c0bba (patch) | |
tree | 421ddc41623361cab1a3f63952e26f30c3b03794 /platform | |
parent | b8d1a6f38dfee21d4fbedcccdb88cf9fdeb32734 (diff) |
linux-ks2: cls: fix deadlock while default cos deletion
Signed-off-by: Ivan Khoronzhuk <ivan.khoronzhuk@linaro.org>
Diffstat (limited to 'platform')
-rw-r--r-- | platform/linux-keystone2/include/odp_cls_internal.h | 2 | ||||
-rw-r--r-- | platform/linux-keystone2/odp_classification.c | 51 | ||||
-rw-r--r-- | platform/linux-keystone2/odp_packet_io.c | 2 |
3 files changed, 41 insertions, 14 deletions
diff --git a/platform/linux-keystone2/include/odp_cls_internal.h b/platform/linux-keystone2/include/odp_cls_internal.h index 0162df89..82baaccc 100644 --- a/platform/linux-keystone2/include/odp_cls_internal.h +++ b/platform/linux-keystone2/include/odp_cls_internal.h @@ -27,5 +27,7 @@ int _cls_disconnect_pmr_list(struct list_head *pmr_list); int _cls_deactivate_pmr_list(struct list_head *pmr_list); int _cls_activate_pmr_list(struct list_head *pmr_list); void _cls_replace_cos(odp_cos_t old_cos, odp_cos_t new_cos); +int __odp_pktio_pmr_cos_nolock(odp_pmr_t pmr, odp_pktio_t src_pktio, + odp_cos_t dst_cos); #endif diff --git a/platform/linux-keystone2/odp_classification.c b/platform/linux-keystone2/odp_classification.c index f48d3906..c77a37f0 100644 --- a/platform/linux-keystone2/odp_classification.c +++ b/platform/linux-keystone2/odp_classification.c @@ -28,7 +28,7 @@ #define ODP_CONFIG_COS_ENTRIES 16 #define ODP_CONFIG_PMR_ENTRIES 128 #define ODP_CONFIG_PMRSET_ENTRIES 64 -#define ODP_CONFIG_PMRS_IN_PMRSET 4 +#define ODP_CONFIG_PMRS_IN_PMRSET 5 #define ODP_CONFIG_PMR_LINK_ENTRIES 128 #define ODP_CONFIG_MAX_TERM_SIZE 16 @@ -396,7 +396,6 @@ int _pmr_hard_update(odp_pmr_t pmr) static inline int __odp_cos_set_pool(odp_cos_t cos, odp_pool_t pool) { - cls_tree_lock(); if (cos == ODP_COS_INVALID || pool == ODP_POOL_INVALID) { cls_tree_unlock(); ODP_ERR("Invalid input parameters\n"); @@ -418,13 +417,18 @@ static inline int __odp_cos_set_pool(odp_cos_t cos, odp_pool_t pool) } entry->pool = pool; - cls_tree_unlock(); return 0; } int odp_cls_cos_pool_set(odp_cos_t cos, odp_pool_t pool) { - return __odp_cos_set_pool(cos, pool); + int ret; + + cls_tree_lock(); + ret = __odp_cos_set_pool(cos, pool); + cls_tree_unlock(); + + return ret; } odp_pool_t odp_cls_cos_pool(odp_cos_t cos) @@ -443,7 +447,6 @@ odp_pool_t odp_cls_cos_pool(odp_cos_t cos) static inline int __odp_cos_queue_set(odp_cos_t cos, odp_queue_t queue) { - cls_tree_lock(); if (cos == ODP_COS_INVALID || queue == ODP_QUEUE_INVALID) { cls_tree_unlock(); ODP_ERR("Invalid input parameters\n"); @@ -465,13 +468,18 @@ static inline int __odp_cos_queue_set(odp_cos_t cos, odp_queue_t queue) } entry->queue = queue; - cls_tree_unlock(); return 0; } int odp_cos_queue_set(odp_cos_t cos, odp_queue_t queue) { - return __odp_cos_queue_set(cos, queue); + int ret; + + cls_tree_lock(); + ret = __odp_cos_queue_set(cos, queue); + cls_tree_unlock(); + + return ret; } odp_queue_t odp_cos_queue(odp_cos_t cos) @@ -528,7 +536,7 @@ odp_cos_t odp_cls_cos_create(const char *name, __odp_cos_set_pool(cos, param->pool)) goto err; if (param->queue != ODP_QUEUE_INVALID && - odp_cos_queue_set(cos, param->queue)) + __odp_cos_queue_set(cos, param->queue)) goto err; if (odp_cos_drop_set(cos, param->drop_policy)) @@ -562,6 +570,9 @@ int odp_cos_drop_set(odp_cos_t cos_id ODP_UNUSED, odp_cls_drop_t drop_policy) if (drop_policy == ODP_COS_DROP_NEVER) return 0; + if (drop_policy == ODP_COS_DROP_POOL) + return 0; + ODP_UNIMPLEMENTED(); return -1; } @@ -1191,12 +1202,11 @@ int odp_pktio_pmr_match_set_cos(odp_pmr_set_t pmr_set, odp_pktio_t src_pktio, return odp_pktio_pmr_cos(pmr, src_pktio, dst_cos); } -int odp_pktio_pmr_cos(odp_pmr_t pmr, odp_pktio_t src_pktio, odp_cos_t dst_cos) +static inline int odp_pktio_pmr_cos_nolock(odp_pmr_t pmr, odp_pktio_t src_pktio, + odp_cos_t dst_cos) { - cls_tree_lock(); if (pmr == ODP_PMR_INVAL || src_pktio == ODP_PKTIO_INVALID || dst_cos == ODP_COS_INVALID) { - cls_tree_unlock(); ODP_ERR("Invalid input parameters\n"); return -1; } @@ -1234,7 +1244,6 @@ int odp_pktio_pmr_cos(odp_pmr_t pmr, odp_pktio_t src_pktio, odp_cos_t dst_cos) /* save layer info to dst CoS */ dst_cos_entry->pmr_layers.all |= (1 << entry->layer); - cls_tree_unlock(); return 0; err: _pktio_rm_pmr_out(src_pktio, &entry->src_cos_node); @@ -1242,10 +1251,26 @@ err: entry->pktio = res_pktio; entry->src_cos = res_src_cos; entry->dst_cos = res_dst_cos; - cls_tree_unlock(); return -1; } +int odp_pktio_pmr_cos(odp_pmr_t pmr, odp_pktio_t src_pktio, odp_cos_t dst_cos) +{ + int ret; + + cls_tree_lock(); + ret = odp_pktio_pmr_cos_nolock(pmr, src_pktio, dst_cos); + cls_tree_unlock(); + + return ret; +} + +int __odp_pktio_pmr_cos_nolock(odp_pmr_t pmr, odp_pktio_t src_pktio, + odp_cos_t dst_cos) +{ + return odp_pktio_pmr_cos_nolock(pmr, src_pktio, dst_cos); +} + int odp_cos_pmr_cos(odp_pmr_t pmr, odp_cos_t src_cos, odp_cos_t dst_cos) { cls_tree_lock(); diff --git a/platform/linux-keystone2/odp_packet_io.c b/platform/linux-keystone2/odp_packet_io.c index da708a0f..5acd740c 100644 --- a/platform/linux-keystone2/odp_packet_io.c +++ b/platform/linux-keystone2/odp_packet_io.c @@ -409,7 +409,7 @@ static int pktio_dummy_pmr_cos_set(odp_pktio_t pktio, odp_cos_t default_cos) entry->pmr_default = pmr; /* connect default pmr/cos to pktio, the PMR will be activated also */ - if (odp_pktio_pmr_cos(pmr, pktio, default_cos) < 0) { + if (__odp_pktio_pmr_cos_nolock(pmr, pktio, default_cos) < 0) { ODP_ERR("Cannot create default CoS\n"); goto destroy_pmr; } |