diff mbox

linux-generic: queue: fix PKTIN queue destroy

Message ID 1424795532-4096-1-git-send-email-stuart.haslam@linaro.org
State Accepted
Commit 8bf0e6ab044a12b79112f7e401c3ee3064d68a8c
Headers show

Commit Message

Stuart Haslam Feb. 24, 2015, 4:32 p.m. UTC
PKTIN queue was not handled correctly. Check queue status instead of
queue type in odp_queue_destroy(). In schedule() check for FREE status
rather than DESTROYED as the preceeding dequeue will have caused a
DESTROYED->FREE transition.

Signed-off-by: Taras Kondratiuk <taras.kondratiuk@linaro.org>
Signed-off-by: Stuart Haslam <stuart.haslam@linaro.org>
---
This is a slightly modified version of a patch Taras sent a while
back, but slipped through the cracks and was never merged;

http://lists.linaro.org/pipermail/lng-odp/2014-December/006702.html

The changes I've made are to resolve an issue I found while testing
that patch;

http://lists.linaro.org/pipermail/lng-odp/2015-January/007507.html

 .../linux-generic/include/odp_queue_internal.h     |  4 +--
 platform/linux-generic/odp_queue.c                 | 39 ++++++++++++----------
 platform/linux-generic/odp_schedule.c              |  2 +-
 3 files changed, 24 insertions(+), 21 deletions(-)

Comments

Maxim Uvarov Feb. 25, 2015, 9:24 a.m. UTC | #1
Merged,
Maxim.

On 02/24/2015 07:32 PM, Stuart Haslam wrote:
> PKTIN queue was not handled correctly. Check queue status instead of
> queue type in odp_queue_destroy(). In schedule() check for FREE status
> rather than DESTROYED as the preceeding dequeue will have caused a
> DESTROYED->FREE transition.
>
> Signed-off-by: Taras Kondratiuk <taras.kondratiuk@linaro.org>
> Signed-off-by: Stuart Haslam <stuart.haslam@linaro.org>
> ---
> This is a slightly modified version of a patch Taras sent a while
> back, but slipped through the cracks and was never merged;
>
> http://lists.linaro.org/pipermail/lng-odp/2014-December/006702.html
>
> The changes I've made are to resolve an issue I found while testing
> that patch;
>
> http://lists.linaro.org/pipermail/lng-odp/2015-January/007507.html
>
>   .../linux-generic/include/odp_queue_internal.h     |  4 +--
>   platform/linux-generic/odp_queue.c                 | 39 ++++++++++++----------
>   platform/linux-generic/odp_schedule.c              |  2 +-
>   3 files changed, 24 insertions(+), 21 deletions(-)
>
> diff --git a/platform/linux-generic/include/odp_queue_internal.h b/platform/linux-generic/include/odp_queue_internal.h
> index bfa36df..65aae14 100644
> --- a/platform/linux-generic/include/odp_queue_internal.h
> +++ b/platform/linux-generic/include/odp_queue_internal.h
> @@ -121,13 +121,13 @@ static inline queue_entry_t *queue_to_qentry(odp_queue_t handle)
>   	return get_qentry(queue_id);
>   }
>   
> -static inline int queue_is_destroyed(odp_queue_t handle)
> +static inline int queue_is_free(odp_queue_t handle)
>   {
>   	queue_entry_t *queue;
>   
>   	queue = queue_to_qentry(handle);
>   
> -	return queue->s.status == QUEUE_STATUS_DESTROYED;
> +	return queue->s.status == QUEUE_STATUS_FREE;
>   }
>   
>   static inline int queue_is_sched(odp_queue_t handle)
> diff --git a/platform/linux-generic/odp_queue.c b/platform/linux-generic/odp_queue.c
> index b945e03..477b5e3 100644
> --- a/platform/linux-generic/odp_queue.c
> +++ b/platform/linux-generic/odp_queue.c
> @@ -259,27 +259,30 @@ int odp_queue_destroy(odp_queue_t handle)
>   	queue->s.enqueue = queue_enq_dummy;
>   	queue->s.enqueue_multi = queue_enq_multi_dummy;
>   
> -	if (queue->s.type == ODP_QUEUE_TYPE_POLL ||
> -	    queue->s.type == ODP_QUEUE_TYPE_PKTOUT) {
> +	switch (queue->s.status) {
> +	case QUEUE_STATUS_READY:
>   		queue->s.status = QUEUE_STATUS_FREE;
>   		queue->s.head = NULL;
>   		queue->s.tail = NULL;
> -	} else if (queue->s.type == ODP_QUEUE_TYPE_SCHED) {
> -		if (queue->s.status == QUEUE_STATUS_SCHED)  {
> -			/*
> -			 * Override dequeue_multi to destroy queue when it will
> -			 * be scheduled next time.
> -			 */
> -			queue->s.status = QUEUE_STATUS_DESTROYED;
> -			queue->s.dequeue_multi = queue_deq_multi_destroy;
> -		} else {
> -			/* Queue won't be scheduled anymore */
> -			odp_buffer_free(queue->s.sched_buf);
> -			queue->s.sched_buf = ODP_BUFFER_INVALID;
> -			queue->s.status = QUEUE_STATUS_FREE;
> -			queue->s.head = NULL;
> -			queue->s.tail = NULL;
> -		}
> +		break;
> +	case QUEUE_STATUS_SCHED:
> +		/*
> +		 * Override dequeue_multi to destroy queue when it will
> +		 * be scheduled next time.
> +		 */
> +		queue->s.status = QUEUE_STATUS_DESTROYED;
> +		queue->s.dequeue_multi = queue_deq_multi_destroy;
> +		break;
> +	case QUEUE_STATUS_NOTSCHED:
> +		/* Queue won't be scheduled anymore */
> +		odp_buffer_free(queue->s.sched_buf);
> +		queue->s.sched_buf = ODP_BUFFER_INVALID;
> +		queue->s.status = QUEUE_STATUS_FREE;
> +		queue->s.head = NULL;
> +		queue->s.tail = NULL;
> +		break;
> +	default:
> +		ODP_ABORT("Unexpected queue status\n");
>   	}
>   	UNLOCK(&queue->s.lock);
>   
> diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux-generic/odp_schedule.c
> index 1a96cd9..dd65168 100644
> --- a/platform/linux-generic/odp_schedule.c
> +++ b/platform/linux-generic/odp_schedule.c
> @@ -336,7 +336,7 @@ static int schedule(odp_queue_t *out_queue, odp_event_t out_ev[],
>   					 */
>   					if (odp_queue_type(queue) ==
>   					    ODP_QUEUE_TYPE_PKTIN &&
> -					    !queue_is_destroyed(queue))
> +					    !queue_is_free(queue))
>   						odp_queue_enq(pri_q, ev);
>   
>   					continue;
diff mbox

Patch

diff --git a/platform/linux-generic/include/odp_queue_internal.h b/platform/linux-generic/include/odp_queue_internal.h
index bfa36df..65aae14 100644
--- a/platform/linux-generic/include/odp_queue_internal.h
+++ b/platform/linux-generic/include/odp_queue_internal.h
@@ -121,13 +121,13 @@  static inline queue_entry_t *queue_to_qentry(odp_queue_t handle)
 	return get_qentry(queue_id);
 }
 
-static inline int queue_is_destroyed(odp_queue_t handle)
+static inline int queue_is_free(odp_queue_t handle)
 {
 	queue_entry_t *queue;
 
 	queue = queue_to_qentry(handle);
 
-	return queue->s.status == QUEUE_STATUS_DESTROYED;
+	return queue->s.status == QUEUE_STATUS_FREE;
 }
 
 static inline int queue_is_sched(odp_queue_t handle)
diff --git a/platform/linux-generic/odp_queue.c b/platform/linux-generic/odp_queue.c
index b945e03..477b5e3 100644
--- a/platform/linux-generic/odp_queue.c
+++ b/platform/linux-generic/odp_queue.c
@@ -259,27 +259,30 @@  int odp_queue_destroy(odp_queue_t handle)
 	queue->s.enqueue = queue_enq_dummy;
 	queue->s.enqueue_multi = queue_enq_multi_dummy;
 
-	if (queue->s.type == ODP_QUEUE_TYPE_POLL ||
-	    queue->s.type == ODP_QUEUE_TYPE_PKTOUT) {
+	switch (queue->s.status) {
+	case QUEUE_STATUS_READY:
 		queue->s.status = QUEUE_STATUS_FREE;
 		queue->s.head = NULL;
 		queue->s.tail = NULL;
-	} else if (queue->s.type == ODP_QUEUE_TYPE_SCHED) {
-		if (queue->s.status == QUEUE_STATUS_SCHED)  {
-			/*
-			 * Override dequeue_multi to destroy queue when it will
-			 * be scheduled next time.
-			 */
-			queue->s.status = QUEUE_STATUS_DESTROYED;
-			queue->s.dequeue_multi = queue_deq_multi_destroy;
-		} else {
-			/* Queue won't be scheduled anymore */
-			odp_buffer_free(queue->s.sched_buf);
-			queue->s.sched_buf = ODP_BUFFER_INVALID;
-			queue->s.status = QUEUE_STATUS_FREE;
-			queue->s.head = NULL;
-			queue->s.tail = NULL;
-		}
+		break;
+	case QUEUE_STATUS_SCHED:
+		/*
+		 * Override dequeue_multi to destroy queue when it will
+		 * be scheduled next time.
+		 */
+		queue->s.status = QUEUE_STATUS_DESTROYED;
+		queue->s.dequeue_multi = queue_deq_multi_destroy;
+		break;
+	case QUEUE_STATUS_NOTSCHED:
+		/* Queue won't be scheduled anymore */
+		odp_buffer_free(queue->s.sched_buf);
+		queue->s.sched_buf = ODP_BUFFER_INVALID;
+		queue->s.status = QUEUE_STATUS_FREE;
+		queue->s.head = NULL;
+		queue->s.tail = NULL;
+		break;
+	default:
+		ODP_ABORT("Unexpected queue status\n");
 	}
 	UNLOCK(&queue->s.lock);
 
diff --git a/platform/linux-generic/odp_schedule.c b/platform/linux-generic/odp_schedule.c
index 1a96cd9..dd65168 100644
--- a/platform/linux-generic/odp_schedule.c
+++ b/platform/linux-generic/odp_schedule.c
@@ -336,7 +336,7 @@  static int schedule(odp_queue_t *out_queue, odp_event_t out_ev[],
 					 */
 					if (odp_queue_type(queue) ==
 					    ODP_QUEUE_TYPE_PKTIN &&
-					    !queue_is_destroyed(queue))
+					    !queue_is_free(queue))
 						odp_queue_enq(pri_q, ev);
 
 					continue;