All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] eal/ipc: stop async IPC loop on callback request
@ 2018-04-10 10:03 Anatoly Burakov
  2018-04-10 13:53 ` Tan, Jianfeng
  2018-04-10 15:28 ` [PATCH v2] " Anatoly Burakov
  0 siblings, 2 replies; 7+ messages in thread
From: Anatoly Burakov @ 2018-04-10 10:03 UTC (permalink / raw)
  To: dev; +Cc: jianfeng.tan, anatoly.burakov

EAL did not stop processing further asynchronous requests on
encountering a request that should trigger the callback. This
resulted in erasing valid requests but not triggering them.

Fix this by stopping the loop once we have a request that we
can trigger. Also, remove unnecessary check for trigger
request being NULL.

Fixes: f05e26051c15 ("eal: add IPC asynchronous request")
Cc: anatoly.burakov@intel.com

Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---
 lib/librte_eal/common/eal_common_proc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_proc.c b/lib/librte_eal/common/eal_common_proc.c
index f98622f..1ea3b58 100644
--- a/lib/librte_eal/common/eal_common_proc.c
+++ b/lib/librte_eal/common/eal_common_proc.c
@@ -510,11 +510,11 @@ async_reply_handle(void *arg __rte_unused)
 					TAILQ_REMOVE(&pending_requests.requests,
 							sr, next);
 					free(sr);
-				} else if (action == ACTION_TRIGGER &&
-						trigger == NULL) {
+				} else if (action == ACTION_TRIGGER) {
 					TAILQ_REMOVE(&pending_requests.requests,
 							sr, next);
 					trigger = sr;
+					break;
 				}
 			}
 		}
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH] eal/ipc: stop async IPC loop on callback request
  2018-04-10 10:03 [PATCH] eal/ipc: stop async IPC loop on callback request Anatoly Burakov
@ 2018-04-10 13:53 ` Tan, Jianfeng
  2018-04-10 14:17   ` Burakov, Anatoly
  2018-04-10 15:28 ` [PATCH v2] " Anatoly Burakov
  1 sibling, 1 reply; 7+ messages in thread
From: Tan, Jianfeng @ 2018-04-10 13:53 UTC (permalink / raw)
  To: Anatoly Burakov, dev



On 4/10/2018 6:03 PM, Anatoly Burakov wrote:
> EAL did not stop processing further asynchronous requests on
> encountering a request that should trigger the callback. This
> resulted in erasing valid requests but not triggering them.

That means one wakeup could process multiple replies, and following 
process_async_request() will erase some valid requests?

>
> Fix this by stopping the loop once we have a request that we
> can trigger. Also, remove unnecessary check for trigger
> request being NULL.
>
> Fixes: f05e26051c15 ("eal: add IPC asynchronous request")
> Cc: anatoly.burakov@intel.com
>
> Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>


> ---
>   lib/librte_eal/common/eal_common_proc.c | 4 ++--
>   1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/lib/librte_eal/common/eal_common_proc.c b/lib/librte_eal/common/eal_common_proc.c
> index f98622f..1ea3b58 100644
> --- a/lib/librte_eal/common/eal_common_proc.c
> +++ b/lib/librte_eal/common/eal_common_proc.c
> @@ -510,11 +510,11 @@ async_reply_handle(void *arg __rte_unused)
>   					TAILQ_REMOVE(&pending_requests.requests,
>   							sr, next);
>   					free(sr);
> -				} else if (action == ACTION_TRIGGER &&
> -						trigger == NULL) {
> +				} else if (action == ACTION_TRIGGER) {
>   					TAILQ_REMOVE(&pending_requests.requests,
>   							sr, next);
>   					trigger = sr;
> +					break;

If I understand it correctly above, break here, we will trigger an async 
action, and then go back to sleep with some ready requests not handled? 
Seems that we shall unlock, process, and lock here. Right?

Thanks,
Jianfeng

>   				}
>   			}
>   		}

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] eal/ipc: stop async IPC loop on callback request
  2018-04-10 13:53 ` Tan, Jianfeng
@ 2018-04-10 14:17   ` Burakov, Anatoly
  2018-04-10 15:16     ` Tan, Jianfeng
  0 siblings, 1 reply; 7+ messages in thread
From: Burakov, Anatoly @ 2018-04-10 14:17 UTC (permalink / raw)
  To: Tan, Jianfeng, dev

On 10-Apr-18 2:53 PM, Tan, Jianfeng wrote:
> 
> 
> On 4/10/2018 6:03 PM, Anatoly Burakov wrote:
>> EAL did not stop processing further asynchronous requests on
>> encountering a request that should trigger the callback. This
>> resulted in erasing valid requests but not triggering them.
> 
> That means one wakeup could process multiple replies, and following 
> process_async_request() will erase some valid requests?

Yes.

> 
>>
>> Fix this by stopping the loop once we have a request that we
>> can trigger. Also, remove unnecessary check for trigger
>> request being NULL.
>>
>> Fixes: f05e26051c15 ("eal: add IPC asynchronous request")
>> Cc: anatoly.burakov@intel.com
>>
>> Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
> 
> 
>> ---
>>   lib/librte_eal/common/eal_common_proc.c | 4 ++--
>>   1 file changed, 2 insertions(+), 2 deletions(-)
>>
>> diff --git a/lib/librte_eal/common/eal_common_proc.c 
>> b/lib/librte_eal/common/eal_common_proc.c
>> index f98622f..1ea3b58 100644
>> --- a/lib/librte_eal/common/eal_common_proc.c
>> +++ b/lib/librte_eal/common/eal_common_proc.c
>> @@ -510,11 +510,11 @@ async_reply_handle(void *arg __rte_unused)
>>                       TAILQ_REMOVE(&pending_requests.requests,
>>                               sr, next);
>>                       free(sr);
>> -                } else if (action == ACTION_TRIGGER &&
>> -                        trigger == NULL) {
>> +                } else if (action == ACTION_TRIGGER) {
>>                       TAILQ_REMOVE(&pending_requests.requests,
>>                               sr, next);
>>                       trigger = sr;
>> +                    break;
> 
> If I understand it correctly above, break here, we will trigger an async 
> action, and then go back to sleep with some ready requests not handled? 
> Seems that we shall unlock, process, and lock here. Right?

Well, we won't go back to sleep - we'll just loop around and come back.

See eal_common_proc.c:472:

	/* sometimes, we don't even wait */
	if (sr->reply_received) {
		nowait = true;
		break;
	}

Followed by line 478:

	if (nowait)
		ret = 0;

Followed by line 495:

	if (ret == 0 || ret == ETIMEDOUT) {

So, having messages with replies already in the queue will cause wait to 
be cancelled. It's not much slower than unlocking, triggering, and 
locking again.

However, if you're OK with lock-loop-unlock-trigger-lock-loop-unlock-... 
sequence until we run out of triggers, then sure, i can add that.

> 
> Thanks,
> Jianfeng
> 
>>                   }
>>               }
>>           }
> 
> 


-- 
Thanks,
Anatoly

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] eal/ipc: stop async IPC loop on callback request
  2018-04-10 14:17   ` Burakov, Anatoly
@ 2018-04-10 15:16     ` Tan, Jianfeng
  0 siblings, 0 replies; 7+ messages in thread
From: Tan, Jianfeng @ 2018-04-10 15:16 UTC (permalink / raw)
  To: Burakov, Anatoly, dev



On 4/10/2018 10:17 PM, Burakov, Anatoly wrote:
> On 10-Apr-18 2:53 PM, Tan, Jianfeng wrote:
>>
>>
>> On 4/10/2018 6:03 PM, Anatoly Burakov wrote:
>>> EAL did not stop processing further asynchronous requests on
>>> encountering a request that should trigger the callback. This
>>> resulted in erasing valid requests but not triggering them.
>>
>> That means one wakeup could process multiple replies, and following 
>> process_async_request() will erase some valid requests?
>
> Yes.
>
>>
>>>
>>> Fix this by stopping the loop once we have a request that we
>>> can trigger. Also, remove unnecessary check for trigger
>>> request being NULL.
>>>
>>> Fixes: f05e26051c15 ("eal: add IPC asynchronous request")
>>> Cc: anatoly.burakov@intel.com
>>>
>>> Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
>>

Acked-by: Jianfeng Tan <jianfeng.tan@intel.com>

>>
>>> ---
>>>   lib/librte_eal/common/eal_common_proc.c | 4 ++--
>>>   1 file changed, 2 insertions(+), 2 deletions(-)
>>>
>>> diff --git a/lib/librte_eal/common/eal_common_proc.c 
>>> b/lib/librte_eal/common/eal_common_proc.c
>>> index f98622f..1ea3b58 100644
>>> --- a/lib/librte_eal/common/eal_common_proc.c
>>> +++ b/lib/librte_eal/common/eal_common_proc.c
>>> @@ -510,11 +510,11 @@ async_reply_handle(void *arg __rte_unused)
>>> TAILQ_REMOVE(&pending_requests.requests,
>>>                               sr, next);
>>>                       free(sr);
>>> -                } else if (action == ACTION_TRIGGER &&
>>> -                        trigger == NULL) {
>>> +                } else if (action == ACTION_TRIGGER) {
>>> TAILQ_REMOVE(&pending_requests.requests,
>>>                               sr, next);
>>>                       trigger = sr;
>>> +                    break;
>>
>> If I understand it correctly above, break here, we will trigger an 
>> async action, and then go back to sleep with some ready requests not 
>> handled? Seems that we shall unlock, process, and lock here. Right?
>
> Well, we won't go back to sleep - we'll just loop around and come back.
>
> See eal_common_proc.c:472:
>
>     /* sometimes, we don't even wait */
>     if (sr->reply_received) {
>         nowait = true;
>         break;
>     }
>
> Followed by line 478:
>
>     if (nowait)
>         ret = 0;
>
> Followed by line 495:
>
>     if (ret == 0 || ret == ETIMEDOUT) {
>
> So, having messages with replies already in the queue will cause wait 
> to be cancelled. It's not much slower than unlocking, triggering, and 
> locking again.

Ah, sorry, I overlooked that fact that every iteration we re-scan the 
request list.

>
> However, if you're OK with 
> lock-loop-unlock-trigger-lock-loop-unlock-... sequence until we run 
> out of triggers, then sure, i can add that.

Don't see the reason for that.

Thanks,
Jianfeng

^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH v2] eal/ipc: stop async IPC loop on callback request
  2018-04-10 10:03 [PATCH] eal/ipc: stop async IPC loop on callback request Anatoly Burakov
  2018-04-10 13:53 ` Tan, Jianfeng
@ 2018-04-10 15:28 ` Anatoly Burakov
  2018-04-13 15:24   ` Tan, Jianfeng
  1 sibling, 1 reply; 7+ messages in thread
From: Anatoly Burakov @ 2018-04-10 15:28 UTC (permalink / raw)
  To: dev; +Cc: jianfeng.tan, anatoly.burakov

EAL did not stop processing further asynchronous requests on
encountering a request that should trigger the callback. This
resulted in erasing valid requests but not triggering them.

Fix this by stopping the loop once we have a request that
can trigger the callback. Once triggered, we go back to scanning
the request queue until there are no more callbacks to trigger.

Fixes: f05e26051c15 ("eal: add IPC asynchronous request")
Cc: anatoly.burakov@intel.com

Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
---

Notes:
    Took the opportunity to simplify some code as well.
    
    The change is a bit more substantial, hence dropping ack.

 lib/librte_eal/common/eal_common_proc.c | 150 ++++++++++++++++++--------------
 1 file changed, 86 insertions(+), 64 deletions(-)

diff --git a/lib/librte_eal/common/eal_common_proc.c b/lib/librte_eal/common/eal_common_proc.c
index f98622f..c888c84 100644
--- a/lib/librte_eal/common/eal_common_proc.c
+++ b/lib/librte_eal/common/eal_common_proc.c
@@ -441,49 +441,87 @@ trigger_async_action(struct pending_request *sr)
 	free(sr->request);
 }
 
+static struct pending_request *
+check_trigger(struct timespec *ts)
+{
+	struct pending_request *next, *cur, *trigger = NULL;
+
+	TAILQ_FOREACH_SAFE(cur, &pending_requests.requests, next, next) {
+		enum async_action action;
+		if (cur->type != REQUEST_TYPE_ASYNC)
+			continue;
+
+		action = process_async_request(cur, ts);
+		if (action == ACTION_FREE) {
+			TAILQ_REMOVE(&pending_requests.requests, cur, next);
+			free(cur);
+		} else if (action == ACTION_TRIGGER) {
+			TAILQ_REMOVE(&pending_requests.requests, cur, next);
+			trigger = cur;
+			break;
+		}
+	}
+	return trigger;
+}
+
+static void
+wait_for_async_messages(void)
+{
+	struct pending_request *sr;
+	struct timespec timeout;
+	bool timedwait = false;
+	bool nowait = false;
+	int ret;
+
+	/* scan through the list and see if there are any timeouts that
+	 * are earlier than our current timeout.
+	 */
+	TAILQ_FOREACH(sr, &pending_requests.requests, next) {
+		if (sr->type != REQUEST_TYPE_ASYNC)
+			continue;
+		if (!timedwait || timespec_cmp(&sr->async.param->end,
+				&timeout) < 0) {
+			memcpy(&timeout, &sr->async.param->end,
+				sizeof(timeout));
+			timedwait = true;
+		}
+
+		/* sometimes, we don't even wait */
+		if (sr->reply_received) {
+			nowait = true;
+			break;
+		}
+	}
+
+	if (nowait)
+		return;
+
+	do {
+		ret = timedwait ?
+			pthread_cond_timedwait(
+				&pending_requests.async_cond,
+				&pending_requests.lock,
+				&timeout) :
+			pthread_cond_wait(
+				&pending_requests.async_cond,
+				&pending_requests.lock);
+	} while (ret != 0 && ret != ETIMEDOUT);
+
+	/* we've been woken up or timed out */
+}
+
 static void *
 async_reply_handle(void *arg __rte_unused)
 {
-	struct pending_request *sr;
 	struct timeval now;
-	struct timespec timeout, ts_now;
+	struct timespec ts_now;
 	while (1) {
 		struct pending_request *trigger = NULL;
-		int ret;
-		bool nowait = false;
-		bool timedwait = false;
 
 		pthread_mutex_lock(&pending_requests.lock);
 
-		/* scan through the list and see if there are any timeouts that
-		 * are earlier than our current timeout.
-		 */
-		TAILQ_FOREACH(sr, &pending_requests.requests, next) {
-			if (sr->type != REQUEST_TYPE_ASYNC)
-				continue;
-			if (!timedwait || timespec_cmp(&sr->async.param->end,
-					&timeout) < 0) {
-				memcpy(&timeout, &sr->async.param->end,
-					sizeof(timeout));
-				timedwait = true;
-			}
-
-			/* sometimes, we don't even wait */
-			if (sr->reply_received) {
-				nowait = true;
-				break;
-			}
-		}
-
-		if (nowait)
-			ret = 0;
-		else if (timedwait)
-			ret = pthread_cond_timedwait(
-					&pending_requests.async_cond,
-					&pending_requests.lock, &timeout);
-		else
-			ret = pthread_cond_wait(&pending_requests.async_cond,
-					&pending_requests.lock);
+		/* we exit this function holding the lock */
+		wait_for_async_messages();
 
 		if (gettimeofday(&now, NULL) < 0) {
 			RTE_LOG(ERR, EAL, "Cannot get current time\n");
@@ -492,38 +530,22 @@ async_reply_handle(void *arg __rte_unused)
 		ts_now.tv_nsec = now.tv_usec * 1000;
 		ts_now.tv_sec = now.tv_sec;
 
-		if (ret == 0 || ret == ETIMEDOUT) {
-			struct pending_request *next;
-			/* we've either been woken up, or we timed out */
+		do {
+			trigger = check_trigger(&ts_now);
+			/* unlock request list */
+			pthread_mutex_unlock(&pending_requests.lock);
 
-			/* we have still the lock, check if anything needs
-			 * processing.
-			 */
-			TAILQ_FOREACH_SAFE(sr, &pending_requests.requests, next,
-					next) {
-				enum async_action action;
-				if (sr->type != REQUEST_TYPE_ASYNC)
-					continue;
-
-				action = process_async_request(sr, &ts_now);
-				if (action == ACTION_FREE) {
-					TAILQ_REMOVE(&pending_requests.requests,
-							sr, next);
-					free(sr);
-				} else if (action == ACTION_TRIGGER &&
-						trigger == NULL) {
-					TAILQ_REMOVE(&pending_requests.requests,
-							sr, next);
-					trigger = sr;
-				}
+			if (trigger) {
+				trigger_async_action(trigger);
+				free(trigger);
+
+				/* we've triggered a callback, but there may be
+				 * more, so lock the list and check again.
+				 */
+				pthread_mutex_lock(&pending_requests.lock);
 			}
-		}
-		pthread_mutex_unlock(&pending_requests.lock);
-		if (trigger) {
-			trigger_async_action(trigger);
-			free(trigger);
-		}
-	};
+		} while (trigger);
+	}
 
 	RTE_LOG(ERR, EAL, "ERROR: asynchronous requests disabled\n");
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH v2] eal/ipc: stop async IPC loop on callback request
  2018-04-10 15:28 ` [PATCH v2] " Anatoly Burakov
@ 2018-04-13 15:24   ` Tan, Jianfeng
  2018-04-16 23:08     ` Thomas Monjalon
  0 siblings, 1 reply; 7+ messages in thread
From: Tan, Jianfeng @ 2018-04-13 15:24 UTC (permalink / raw)
  To: Anatoly Burakov, dev



On 4/10/2018 11:28 PM, Anatoly Burakov wrote:
> EAL did not stop processing further asynchronous requests on
> encountering a request that should trigger the callback. This
> resulted in erasing valid requests but not triggering them.
>
> Fix this by stopping the loop once we have a request that
> can trigger the callback. Once triggered, we go back to scanning
> the request queue until there are no more callbacks to trigger.
>
> Fixes: f05e26051c15 ("eal: add IPC asynchronous request")
> Cc: anatoly.burakov@intel.com
>
> Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>

Acked-by: Jianfeng Tan <jianfeng.tan@intel.com>

Thanks!

> ---
>
> Notes:
>      Took the opportunity to simplify some code as well.
>      
>      The change is a bit more substantial, hence dropping ack.
>
>   lib/librte_eal/common/eal_common_proc.c | 150 ++++++++++++++++++--------------
>   1 file changed, 86 insertions(+), 64 deletions(-)
>
> diff --git a/lib/librte_eal/common/eal_common_proc.c b/lib/librte_eal/common/eal_common_proc.c
> index f98622f..c888c84 100644
> --- a/lib/librte_eal/common/eal_common_proc.c
> +++ b/lib/librte_eal/common/eal_common_proc.c
> @@ -441,49 +441,87 @@ trigger_async_action(struct pending_request *sr)
>   	free(sr->request);
>   }
>   
> +static struct pending_request *
> +check_trigger(struct timespec *ts)
> +{
> +	struct pending_request *next, *cur, *trigger = NULL;
> +
> +	TAILQ_FOREACH_SAFE(cur, &pending_requests.requests, next, next) {
> +		enum async_action action;
> +		if (cur->type != REQUEST_TYPE_ASYNC)
> +			continue;
> +
> +		action = process_async_request(cur, ts);
> +		if (action == ACTION_FREE) {
> +			TAILQ_REMOVE(&pending_requests.requests, cur, next);
> +			free(cur);
> +		} else if (action == ACTION_TRIGGER) {
> +			TAILQ_REMOVE(&pending_requests.requests, cur, next);
> +			trigger = cur;
> +			break;
> +		}
> +	}
> +	return trigger;
> +}
> +
> +static void
> +wait_for_async_messages(void)
> +{
> +	struct pending_request *sr;
> +	struct timespec timeout;
> +	bool timedwait = false;
> +	bool nowait = false;
> +	int ret;
> +
> +	/* scan through the list and see if there are any timeouts that
> +	 * are earlier than our current timeout.
> +	 */
> +	TAILQ_FOREACH(sr, &pending_requests.requests, next) {
> +		if (sr->type != REQUEST_TYPE_ASYNC)
> +			continue;
> +		if (!timedwait || timespec_cmp(&sr->async.param->end,
> +				&timeout) < 0) {
> +			memcpy(&timeout, &sr->async.param->end,
> +				sizeof(timeout));
> +			timedwait = true;
> +		}
> +
> +		/* sometimes, we don't even wait */
> +		if (sr->reply_received) {
> +			nowait = true;
> +			break;
> +		}
> +	}
> +
> +	if (nowait)
> +		return;
> +
> +	do {
> +		ret = timedwait ?
> +			pthread_cond_timedwait(
> +				&pending_requests.async_cond,
> +				&pending_requests.lock,
> +				&timeout) :
> +			pthread_cond_wait(
> +				&pending_requests.async_cond,
> +				&pending_requests.lock);
> +	} while (ret != 0 && ret != ETIMEDOUT);
> +
> +	/* we've been woken up or timed out */
> +}
> +
>   static void *
>   async_reply_handle(void *arg __rte_unused)
>   {
> -	struct pending_request *sr;
>   	struct timeval now;
> -	struct timespec timeout, ts_now;
> +	struct timespec ts_now;
>   	while (1) {
>   		struct pending_request *trigger = NULL;
> -		int ret;
> -		bool nowait = false;
> -		bool timedwait = false;
>   
>   		pthread_mutex_lock(&pending_requests.lock);
>   
> -		/* scan through the list and see if there are any timeouts that
> -		 * are earlier than our current timeout.
> -		 */
> -		TAILQ_FOREACH(sr, &pending_requests.requests, next) {
> -			if (sr->type != REQUEST_TYPE_ASYNC)
> -				continue;
> -			if (!timedwait || timespec_cmp(&sr->async.param->end,
> -					&timeout) < 0) {
> -				memcpy(&timeout, &sr->async.param->end,
> -					sizeof(timeout));
> -				timedwait = true;
> -			}
> -
> -			/* sometimes, we don't even wait */
> -			if (sr->reply_received) {
> -				nowait = true;
> -				break;
> -			}
> -		}
> -
> -		if (nowait)
> -			ret = 0;
> -		else if (timedwait)
> -			ret = pthread_cond_timedwait(
> -					&pending_requests.async_cond,
> -					&pending_requests.lock, &timeout);
> -		else
> -			ret = pthread_cond_wait(&pending_requests.async_cond,
> -					&pending_requests.lock);
> +		/* we exit this function holding the lock */
> +		wait_for_async_messages();
>   
>   		if (gettimeofday(&now, NULL) < 0) {
>   			RTE_LOG(ERR, EAL, "Cannot get current time\n");
> @@ -492,38 +530,22 @@ async_reply_handle(void *arg __rte_unused)
>   		ts_now.tv_nsec = now.tv_usec * 1000;
>   		ts_now.tv_sec = now.tv_sec;
>   
> -		if (ret == 0 || ret == ETIMEDOUT) {
> -			struct pending_request *next;
> -			/* we've either been woken up, or we timed out */
> +		do {
> +			trigger = check_trigger(&ts_now);
> +			/* unlock request list */
> +			pthread_mutex_unlock(&pending_requests.lock);
>   
> -			/* we have still the lock, check if anything needs
> -			 * processing.
> -			 */
> -			TAILQ_FOREACH_SAFE(sr, &pending_requests.requests, next,
> -					next) {
> -				enum async_action action;
> -				if (sr->type != REQUEST_TYPE_ASYNC)
> -					continue;
> -
> -				action = process_async_request(sr, &ts_now);
> -				if (action == ACTION_FREE) {
> -					TAILQ_REMOVE(&pending_requests.requests,
> -							sr, next);
> -					free(sr);
> -				} else if (action == ACTION_TRIGGER &&
> -						trigger == NULL) {
> -					TAILQ_REMOVE(&pending_requests.requests,
> -							sr, next);
> -					trigger = sr;
> -				}
> +			if (trigger) {
> +				trigger_async_action(trigger);
> +				free(trigger);
> +
> +				/* we've triggered a callback, but there may be
> +				 * more, so lock the list and check again.
> +				 */
> +				pthread_mutex_lock(&pending_requests.lock);
>   			}
> -		}
> -		pthread_mutex_unlock(&pending_requests.lock);
> -		if (trigger) {
> -			trigger_async_action(trigger);
> -			free(trigger);
> -		}
> -	};
> +		} while (trigger);
> +	}
>   
>   	RTE_LOG(ERR, EAL, "ERROR: asynchronous requests disabled\n");
>   

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH v2] eal/ipc: stop async IPC loop on callback request
  2018-04-13 15:24   ` Tan, Jianfeng
@ 2018-04-16 23:08     ` Thomas Monjalon
  0 siblings, 0 replies; 7+ messages in thread
From: Thomas Monjalon @ 2018-04-16 23:08 UTC (permalink / raw)
  To: Anatoly Burakov; +Cc: dev, Tan, Jianfeng

13/04/2018 17:24, Tan, Jianfeng:
> 
> On 4/10/2018 11:28 PM, Anatoly Burakov wrote:
> > EAL did not stop processing further asynchronous requests on
> > encountering a request that should trigger the callback. This
> > resulted in erasing valid requests but not triggering them.
> >
> > Fix this by stopping the loop once we have a request that
> > can trigger the callback. Once triggered, we go back to scanning
> > the request queue until there are no more callbacks to trigger.
> >
> > Fixes: f05e26051c15 ("eal: add IPC asynchronous request")
> > Cc: anatoly.burakov@intel.com
> >
> > Signed-off-by: Anatoly Burakov <anatoly.burakov@intel.com>
> 
> Acked-by: Jianfeng Tan <jianfeng.tan@intel.com>

Applied, thanks

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2018-04-16 23:08 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-04-10 10:03 [PATCH] eal/ipc: stop async IPC loop on callback request Anatoly Burakov
2018-04-10 13:53 ` Tan, Jianfeng
2018-04-10 14:17   ` Burakov, Anatoly
2018-04-10 15:16     ` Tan, Jianfeng
2018-04-10 15:28 ` [PATCH v2] " Anatoly Burakov
2018-04-13 15:24   ` Tan, Jianfeng
2018-04-16 23:08     ` Thomas Monjalon

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.