From: Anatoly Burakov Date: Tue, 13 Nov 2018 18:03:52 +0000 (+0000) Subject: ipc: remove panic in async request X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=45e5f49e87fb;p=dpdk.git ipc: remove panic in async request EAL should not crash when setting alarm fails. Also, remove the profanity in error message. Fixes: daf9bfca717e ("ipc: remove thread for async requests") Cc: stable@dpdk.org Signed-off-by: Stephen Hemminger Signed-off-by: Anatoly Burakov --- diff --git a/lib/librte_eal/common/eal_common_proc.c b/lib/librte_eal/common/eal_common_proc.c index 97663d3baf..f65ef56c01 100644 --- a/lib/librte_eal/common/eal_common_proc.c +++ b/lib/librte_eal/common/eal_common_proc.c @@ -800,7 +800,7 @@ mp_request_async(const char *dst, struct rte_mp_msg *req, { struct rte_mp_msg *reply_msg; struct pending_request *pending_req, *exist; - int ret; + int ret = -1; pending_req = calloc(1, sizeof(*pending_req)); reply_msg = calloc(1, sizeof(*reply_msg)); @@ -827,6 +827,28 @@ mp_request_async(const char *dst, struct rte_mp_msg *req, goto fail; } + /* + * set the alarm before sending message. there are two possible error + * scenarios to consider here: + * + * - if the alarm set fails, we free the memory right there + * - if the alarm set succeeds but sending message fails, then the alarm + * will trigger and clean up the memory + * + * Even if the alarm triggers too early (i.e. immediately), we're still + * holding the lock to pending requests queue, so the interrupt thread + * will just spin until we release the lock, and either release the + * memory, or doesn't find any pending requests in the queue because we + * never added any due to send message failure. + */ + if (rte_eal_alarm_set(ts->tv_sec * 1000000 + ts->tv_nsec / 1000, + async_reply_handle, pending_req) < 0) { + RTE_LOG(ERR, EAL, "Fail to set alarm for request %s:%s\n", + dst, req->name); + ret = -1; + goto fail; + } + ret = send_msg(dst, req, MP_REQ); if (ret < 0) { RTE_LOG(ERR, EAL, "Fail to send request %s:%s\n", @@ -841,13 +863,6 @@ mp_request_async(const char *dst, struct rte_mp_msg *req, param->user_reply.nb_sent++; - if (rte_eal_alarm_set(ts->tv_sec * 1000000 + ts->tv_nsec / 1000, - async_reply_handle, pending_req) < 0) { - RTE_LOG(ERR, EAL, "Fail to set alarm for request %s:%s\n", - dst, req->name); - rte_panic("Fix the above shit to properly free all memory\n"); - } - return 0; fail: free(pending_req);