diff mbox

linux-generic: pktio: handle transient output queue nonempty conditions

Message ID 1459037114-4678-1-git-send-email-bill.fischofer@linaro.org
State Superseded
Headers show

Commit Message

Bill Fischofer March 27, 2016, 12:05 a.m. UTC
Out queues are normally empty but any non-empty state should be
very transient. Retry odp_queue_destroy() operation when performing
destroy_out_queues() function to handle such cases. This addresses
bug https://bugs.linaro.org/show_bug.cgi?id=2089

Signed-off-by: Bill Fischofer <bill.fischofer@linaro.org>
---
 platform/linux-generic/odp_packet_io.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

Comments

Maxim Uvarov April 1, 2016, 3:58 p.m. UTC | #1
On 03/27/16 03:05, Bill Fischofer wrote:
> Out queues are normally empty but any non-empty state should be
> very transient. Retry odp_queue_destroy() operation when performing
> destroy_out_queues() function to handle such cases. This addresses
> bug https://bugs.linaro.org/show_bug.cgi?id=2089
>
> Signed-off-by: Bill Fischofer <bill.fischofer@linaro.org>
> ---
>   platform/linux-generic/odp_packet_io.c | 4 +++-
>   1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux-generic/odp_packet_io.c
> index 9192be2..b29623e 100644
> --- a/platform/linux-generic/odp_packet_io.c
> +++ b/platform/linux-generic/odp_packet_io.c
> @@ -300,7 +300,9 @@ static void destroy_out_queues(pktio_entry_t *entry, int num)
>   
>   	for (i = 0; i < num; i++) {
>   		if (entry->s.out_queue[i].queue != ODP_QUEUE_INVALID) {
> -			odp_queue_destroy(entry->s.out_queue[i].queue);
> +			while (odp_queue_destroy(entry->s.out_queue[i].queue)
> +			       != 0)
> +				;
Bill, I think it's a little bit risky to do that even for linux-generic. 
Too match cases
where we can lock up forever:

int odp_queue_destroy(odp_queue_t handle)
{


         if (handle == ODP_QUEUE_INVALID)
                 return -1;

         LOCK(&queue->s.lock);
         if (queue->s.status == QUEUE_STATUS_FREE) {
                 UNLOCK(&queue->s.lock);
                 ODP_ERR("queue \"%s\" already free\n", queue->s.name);
                 return -1;
         }
         if (queue->s.status == QUEUE_STATUS_DESTROYED) {
                 UNLOCK(&queue->s.lock);
                 ODP_ERR("queue \"%s\" already destroyed\n", queue->s.name);
                 return -1;
         }
         if (queue->s.head != NULL) {
                 UNLOCK(&queue->s.lock);
                 ODP_ERR("queue \"%s\" not empty\n", queue->s.name);
                 return -1;
         }
         if (queue_is_ordered(queue) && queue->s.reorder_head) {
                 UNLOCK(&queue->s.lock);
                 ODP_ERR("queue \"%s\" reorder queue not empty\n",
                         queue->s.name);
                 return -1;
         }



Maxim.


>   			entry->s.out_queue[i].queue = ODP_QUEUE_INVALID;
>   		}
>   	}
Bill Fischofer April 2, 2016, 1:53 p.m. UTC | #2
On Fri, Apr 1, 2016 at 10:58 AM, Maxim Uvarov <maxim.uvarov@linaro.org>
wrote:

> On 03/27/16 03:05, Bill Fischofer wrote:

>

>> Out queues are normally empty but any non-empty state should be

>> very transient. Retry odp_queue_destroy() operation when performing

>> destroy_out_queues() function to handle such cases. This addresses

>> bug https://bugs.linaro.org/show_bug.cgi?id=2089

>>

>> Signed-off-by: Bill Fischofer <bill.fischofer@linaro.org>

>> ---

>>   platform/linux-generic/odp_packet_io.c | 4 +++-

>>   1 file changed, 3 insertions(+), 1 deletion(-)

>>

>> diff --git a/platform/linux-generic/odp_packet_io.c

>> b/platform/linux-generic/odp_packet_io.c

>> index 9192be2..b29623e 100644

>> --- a/platform/linux-generic/odp_packet_io.c

>> +++ b/platform/linux-generic/odp_packet_io.c

>> @@ -300,7 +300,9 @@ static void destroy_out_queues(pktio_entry_t *entry,

>> int num)

>>         for (i = 0; i < num; i++) {

>>                 if (entry->s.out_queue[i].queue != ODP_QUEUE_INVALID) {

>> -                       odp_queue_destroy(entry->s.out_queue[i].queue);

>> +                       while

>> (odp_queue_destroy(entry->s.out_queue[i].queue)

>> +                              != 0)

>> +                               ;

>>

> Bill, I think it's a little bit risky to do that even for linux-generic.

> Too match cases

> where we can lock up forever:

>


Good point.  I've submitted a v2 that changes this to an ODP_ASSERT() which
will abort rather than allow a
memory leak.


>

> int odp_queue_destroy(odp_queue_t handle)

> {

>

>

>         if (handle == ODP_QUEUE_INVALID)

>                 return -1;

>

>         LOCK(&queue->s.lock);

>         if (queue->s.status == QUEUE_STATUS_FREE) {

>                 UNLOCK(&queue->s.lock);

>                 ODP_ERR("queue \"%s\" already free\n", queue->s.name);

>                 return -1;

>         }

>         if (queue->s.status == QUEUE_STATUS_DESTROYED) {

>                 UNLOCK(&queue->s.lock);

>                 ODP_ERR("queue \"%s\" already destroyed\n", queue->s.name

> );

>                 return -1;

>         }

>         if (queue->s.head != NULL) {

>                 UNLOCK(&queue->s.lock);

>                 ODP_ERR("queue \"%s\" not empty\n", queue->s.name);

>                 return -1;

>         }

>         if (queue_is_ordered(queue) && queue->s.reorder_head) {

>                 UNLOCK(&queue->s.lock);

>                 ODP_ERR("queue \"%s\" reorder queue not empty\n",

>                         queue->s.name);

>                 return -1;

>         }

>

>

>

> Maxim.

>

>

>                         entry->s.out_queue[i].queue = ODP_QUEUE_INVALID;

>>                 }

>>         }

>>

>

> _______________________________________________

> lng-odp mailing list

> lng-odp@lists.linaro.org

> https://lists.linaro.org/mailman/listinfo/lng-odp

>
diff mbox

Patch

diff --git a/platform/linux-generic/odp_packet_io.c b/platform/linux-generic/odp_packet_io.c
index 9192be2..b29623e 100644
--- a/platform/linux-generic/odp_packet_io.c
+++ b/platform/linux-generic/odp_packet_io.c
@@ -300,7 +300,9 @@  static void destroy_out_queues(pktio_entry_t *entry, int num)
 
 	for (i = 0; i < num; i++) {
 		if (entry->s.out_queue[i].queue != ODP_QUEUE_INVALID) {
-			odp_queue_destroy(entry->s.out_queue[i].queue);
+			while (odp_queue_destroy(entry->s.out_queue[i].queue)
+			       != 0)
+				;
 			entry->s.out_queue[i].queue = ODP_QUEUE_INVALID;
 		}
 	}