aboutsummaryrefslogtreecommitdiff
path: root/platform
diff options
context:
space:
mode:
authorIvan Khoronzhuk <ivan.khoronzhuk@linaro.org>2016-01-11 21:39:58 +0200
committerIvan Khoronzhuk <ivan.khoronzhuk@linaro.org>2016-01-12 19:33:06 +0200
commit38d0735e8df45908766c86d244bd1f4f2b9c0bba (patch)
tree421ddc41623361cab1a3f63952e26f30c3b03794 /platform
parentb8d1a6f38dfee21d4fbedcccdb88cf9fdeb32734 (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.h2
-rw-r--r--platform/linux-keystone2/odp_classification.c51
-rw-r--r--platform/linux-keystone2/odp_packet_io.c2
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;
}