Prevent responses to timed-out NameServer requests from disrupting later reqs 3.23.00.00_eng
authorvwan@ti.com <vwan@ti.com>
Tue, 22 Jul 2014 20:07:20 +0000 (13:07 -0700)
committerRobert Tivy <rtivy@ti.com>
Tue, 5 Aug 2014 17:49:08 +0000 (10:49 -0700)
This commit fixes the issue in SDOCM00112106 in QNX and BIOS. It adds a
sequence number to each NameServer message, so that when responses come
back this number can be used to identify the relevant response and ignore
the stale ones.

Signed-off-by: VW <vwan@ti.com>
hlos_common/include/_NameServerRemoteRpmsg.h
packages/ti/ipc/namesrv/NameServerRemoteRpmsg.c
packages/ti/ipc/namesrv/_NameServerRemoteRpmsg.h
qnx/src/ipc3x_dev/ti/syslink/utils/hlos/knl/NameServer_daemon.c

index dafc3447599feb6a814a43f7e6364bddd416398b..b11334a75dac2fa5cf9f34811d9d790e07637ce9 100644 (file)
@@ -49,6 +49,7 @@ typedef struct NameServerMsg {
     Bits32  value;              /* holds value                      */
     Bits32  request;            /* whether its a request/response   */
     Bits32  requestStatus;      /* status of request                */
+    Bits32  seqNum;             /* NameServer request sequence #    */
                                 /* name of NameServer instance      */
     Bits32  instanceName[NAMEARRAYSZIE];
                                 /* name of NameServer entry         */
index f412927997c9756497a294290c43ac73ccf33e14..f86734924676aabdd90dc6833478713266bd3fab 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2013, Texas Instruments Incorporated
+ * Copyright (c) 2013-2014, Texas Instruments Incorporated
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -163,6 +163,8 @@ Int NameServerRemoteRpmsg_get(NameServerRemoteRpmsg_Object *obj,
     NameServerRemote_Msg  *replyMsg;
     Semaphore_Handle      semRemoteWait =
                            NameServerRemoteRpmsg_module->semRemoteWait;
+    static UInt32         seqNum = 0;
+    Bool                  done = FALSE;
 
     GateMutex_Handle gateMutex = NameServerRemoteRpmsg_module->gateMutex;
 
@@ -181,6 +183,7 @@ Int NameServerRemoteRpmsg_get(NameServerRemoteRpmsg_Object *obj,
     msg.request = NameServerRemoteRpmsg_REQUEST;
     msg.requestStatus = 0;
     msg.valueLen = *valueLen;
+    msg.seqNum = seqNum++;
 
     len = strlen(instanceName);
     Assert_isTrue(len < MAXNAMEINCHAR, NameServerRemoteRpmsg_A_nameIsTooLong);
@@ -197,45 +200,53 @@ Int NameServerRemoteRpmsg_get(NameServerRemoteRpmsg_Object *obj,
     RPMessage_send(obj->remoteProcId, NameServerRemoteRpmsg_module->nsPort,
                RPMSG_MESSAGEQ_PORT, (Ptr)&msg, sizeof(msg));
 
-    /* Now pend for response */
-    status = Semaphore_pend(semRemoteWait, NameServerRemoteRpmsg_timeout);
+    while (!done) {
+        /* Now pend for response */
+        status = Semaphore_pend(semRemoteWait, NameServerRemoteRpmsg_timeout);
 
-    if (status == FALSE) {
-        Log_print0(Diags_INFO, FXNN": Wait for NS reply timed out\n");
-        /* return timeout failure */
-        return (NameServer_E_TIMEOUT);
-    }
+        if (status == FALSE) {
+            Log_print0(Diags_INFO, FXNN": Wait for NS reply timed out\n");
+            /* return timeout failure */
+            return (NameServer_E_TIMEOUT);
+        }
 
-    /* get the message */
-    replyMsg = NameServerRemoteRpmsg_module->nsMsg;
+        /* get the message */
+        replyMsg = NameServerRemoteRpmsg_module->nsMsg;
+
+        if (replyMsg->seqNum != seqNum - 1) {
+            /* Ignore responses without current sequence # */
+            continue;
+        }
 
-    if (replyMsg->requestStatus) {
-        /* name is found */
+        if (replyMsg->requestStatus) {
+            /* name is found */
 
-        /* set length to amount of data that was copied */
-        *valueLen = replyMsg->valueLen;
+            /* set length to amount of data that was copied */
+            *valueLen = replyMsg->valueLen;
+
+            /* set the contents of value */
+            if (*valueLen <= sizeof (Bits32)) {
+                memcpy(value, &(replyMsg->value), sizeof(Bits32));
+            }
+            else {
+                memcpy(value, replyMsg->valueBuf, *valueLen);
+            }
 
-        /* set the contents of value */
-        if (*valueLen <= sizeof (Bits32)) {
-            memcpy(value, &(replyMsg->value), sizeof(Bits32));
+            /* set the status to success */
+            status = NameServer_S_SUCCESS;
+            Log_print4(Diags_INFO, FXNN": Reply from: %d, %s:%s, value: 0x%x...\n",
+                  obj->remoteProcId, (IArg)msg.instanceName, (IArg)msg.name,
+                  *(UInt32 *)value);
         }
         else {
-            memcpy(value, replyMsg->valueBuf, *valueLen);
-        }
-
-        /* set the status to success */
-        status = NameServer_S_SUCCESS;
-        Log_print4(Diags_INFO, FXNN": Reply from: %d, %s:%s, value: 0x%x...\n",
-              obj->remoteProcId, (IArg)msg.instanceName, (IArg)msg.name,
-              *(UInt32 *)value);
-    }
-    else {
-        /* name is not found */
-        Log_print2(Diags_INFO, FXNN": value for %s:%s not found.\n",
+            /* name is not found */
+            Log_print2(Diags_INFO, FXNN": value for %s:%s not found.\n",
                    (IArg)msg.instanceName, (IArg)msg.name);
 
-        /* set status to not found */
-        status = NameServer_E_NOTFOUND;
+            /* set status to not found */
+            status = NameServer_E_NOTFOUND;
+        }
+        done = TRUE;
     }
 
 exit:
index 84412283c1f3b6ed18f1cfcdc8fba041940dbfe1..e95a26aae65e931fadeeb0207172de588a873506 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2013, Texas Instruments Incorporated
+ * Copyright (c) 2012-2014, Texas Instruments Incorporated
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -48,6 +48,7 @@ typedef struct NameServerRemote_Msg {
     Bits32  value;              /* holds value if len <= 4          */
     Bits32  request;            /* whether its a request/response   */
     Bits32  requestStatus;      /* status of request                */
+    Bits32  seqNum;             /* NameServer request sequence #    */
                                 /* name of NameServer instance      */
     Bits32  instanceName[NAMEARRAYSZIE];
                                 /* name of NameServer entry         */
index f131c3ee656d3d8259e5dbe0d789b922d718415a..bd7cc2a0fb3c618a05eaa64bd2529646984b03ba 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2012-2013, Texas Instruments Incorporated
+ * Copyright (c) 2012-2014, Texas Instruments Incorporated
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -805,6 +805,8 @@ Int NameServer_getRemote(NameServer_Handle handle,
     struct timeval tv;
     char buf = '1';
     int numBytes;
+    static int seqNum = 0;
+    Bool done = FALSE;
 
     pthread_mutex_lock(&NameServer_module->modGate);
 
@@ -817,6 +819,7 @@ Int NameServer_getRemote(NameServer_Handle handle,
     nsMsg.request = NAMESERVER_REQUEST;
     nsMsg.requestStatus = 0;
     nsMsg.valueLen = *len;
+    nsMsg.seqNum = seqNum++;
 
     strncpy((char *)nsMsg.instanceName, obj->name, strlen(obj->name) + 1);
     strncpy((char *)nsMsg.name, name, strlen(name) + 1);
@@ -824,6 +827,7 @@ Int NameServer_getRemote(NameServer_Handle handle,
     LOG2("NameServer_getRemote: Requesting from procId %d, %s:",
            procId, (String)nsMsg.instanceName)
     LOG1("%s...\n", (String)nsMsg.name)
+
     /* send message */
     mqcStatus = MessageQCopy_send(procId, MultiProc_self(), MESSAGEQ_RPMSG_PORT,
             RPMSG_RESERVED_ADDRESSES, &nsMsg, sizeof(NameServerMsg),
@@ -834,65 +838,72 @@ Int NameServer_getRemote(NameServer_Handle handle,
         goto exit;
     }
 
-    /* Block on waitFd for signal from listener thread: */
-    waitFd = NameServer_module->waitFdR;
-    FD_ZERO(&rfds);
-    FD_SET(waitFd, &rfds);
-    maxfd = waitFd + 1;
-    LOG1("NameServer_getRemote: pending on waitFd: %d\n", waitFd)
-    ret = select(maxfd, &rfds, NULL, NULL, &tv);
-    if (ret == -1) {
-        LOG0("NameServer_getRemote: select failed.")
-        status = NameServer_E_FAIL;
-        goto exit;
-    }
-    else if (!ret) {
-        LOG0("NameServer_getRemote: select timed out.\n")
-        status = NameServer_E_TIMEOUT;
-        goto exit;
-    }
+    while (!done) {
+        /* Block on waitFd for signal from listener thread: */
+        waitFd = NameServer_module->waitFdR;
+        FD_ZERO(&rfds);
+        FD_SET(waitFd, &rfds);
+        maxfd = waitFd + 1;
+        LOG1("NameServer_getRemote: pending on waitFd: %d\n", waitFd)
+        ret = select(maxfd, &rfds, NULL, NULL, &tv);
+        if (ret == -1) {
+            LOG0("NameServer_getRemote: select failed.")
+            status = NameServer_E_FAIL;
+            goto exit;
+        }
+        else if (!ret) {
+            LOG0("NameServer_getRemote: select timed out.\n")
+            status = NameServer_E_TIMEOUT;
+            goto exit;
+        }
+
+        if (FD_ISSET(waitFd, &rfds)) {
+            /* Read, just to balance the write: */
+            numBytes = read(waitFd, &buf, sizeof(buf));
 
-    if (FD_ISSET(waitFd, &rfds)) {
-        /* Read, just to balance the write: */
-        numBytes = read(waitFd, &buf, sizeof(buf));
+            /* Process response: */
+            replyMsg = &NameServer_module->nsMsg;
 
-        /* Process response: */
-        replyMsg = &NameServer_module->nsMsg;
+            if (replyMsg->seqNum != seqNum - 1) {
+                /* Ignore responses without current sequence # */
+                continue;
+            }
 
-        if (replyMsg->requestStatus) {
-            /* name is found */
+            if (replyMsg->requestStatus) {
+                /* name is found */
 
-            /* set length to amount of data that was copied */
-            *len = replyMsg->valueLen;
+                /* set length to amount of data that was copied */
+                *len = replyMsg->valueLen;
 
-            /* set the contents of value */
-            if (*len <= sizeof (Bits32)) {
-                *(UInt32 *)value = (UInt32)replyMsg->value;
-                LOG2("NameServer_getRemote: Reply from: %d, %s:",
-                    procId, (String)replyMsg->instanceName)
-                LOG2("%s, value: 0x%x...\n",
-                    (String)replyMsg->name, *(UInt32 *)value)
+                /* set the contents of value */
+                if (*len <= sizeof (Bits32)) {
+                    *(UInt32 *)value = (UInt32)replyMsg->value;
+                    LOG2("NameServer_getRemote: Reply from: %d, %s:",
+                        procId, (String)replyMsg->instanceName)
+                    LOG2("%s, value: 0x%x...\n",
+                        (String)replyMsg->name, *(UInt32 *)value)
+                }
+                else {
+                    memcpy(value, replyMsg->valueBuf, *len);
+                    LOG2("NameServer_getRemote: Reply from: %d, %s:",
+                        procId, (String)replyMsg->instanceName)
+                    LOG2("%s, value buffer at address: 0x%p...\n",
+                        (String)replyMsg->name, value)
+                }
+
+                goto exit;
             }
             else {
-                memcpy(value, replyMsg->valueBuf, *len);
-                LOG2("NameServer_getRemote: Reply from: %d, %s:",
-                    procId, (String)replyMsg->instanceName)
-                LOG2("%s, value buffer at address: 0x%p...\n",
-                    (String)replyMsg->name, value)
-            }
+                /* name is not found */
+                LOG2("NameServer_getRemote: value for %s:%s not found.\n",
+                     (String)replyMsg->instanceName, (String)replyMsg->name)
 
-            goto exit;
-        }
-        else {
-            /* name is not found */
-            LOG2("NameServer_getRemote: value for %s:%s not found.\n",
-                 (String)replyMsg->instanceName, (String)replyMsg->name)
-
-            /* set status to not found */
-            status = NameServer_E_NOTFOUND;
+                /* set status to not found */
+                status = NameServer_E_NOTFOUND;
+            }
         }
+        done = TRUE;
     }
-
 exit:
     pthread_mutex_unlock(&NameServer_module->modGate);