rx-do-housekeeping-on-packets-with-new-flags-20010907
authorNickolai Zeldovich <kolya@mit.edu>
Fri, 7 Sep 2001 21:47:57 +0000 (21:47 +0000)
committerDerrick Brashear <shadow@dementia.org>
Fri, 7 Sep 2001 21:47:57 +0000 (21:47 +0000)
keep better track of packet state using flags in packet header indicating
which packets are in acked state and which are free

src/rx/rx.c
src/rx/rx_packet.c
src/rx/rx_packet.h

index 83f7eb4..c74472d 100644 (file)
@@ -3326,12 +3326,12 @@ struct rx_packet *rxi_ReceiveAckPacket(call, np, istack)
      * set the ack bits in the packets and have rxi_Start remove the packets
      * when it's done transmitting.
      */
-       if (!tp->acked) {
+       if (!(tp->flags & RX_PKTFLAG_ACKED)) {
            newAckCount++;
        }
        if (call->flags & RX_CALL_TQ_BUSY) {
 #ifdef RX_ENABLE_LOCKS
-           tp->acked = 1;
+           tp->flags |= RX_PKTFLAG_ACKED;
            call->flags |= RX_CALL_TQ_SOME_ACKED;
 #else /* RX_ENABLE_LOCKS */
            break;
@@ -3400,17 +3400,17 @@ struct rx_packet *rxi_ReceiveAckPacket(call, np, istack)
         * out of sequence. */
        if (tp->header.seq < first) {
            /* Implicit ack information */
-           if (!tp->acked) {
+           if (!(tp->flags & RX_PKTFLAG_ACKED)) {
                newAckCount++;
            }
-           tp->acked = 1;
+           tp->flags |= RX_PKTFLAG_ACKED;
        }
        else if (tp->header.seq < first + nAcks) {
            /* Explicit ack information:  set it in the packet appropriately */
            if (ap->acks[tp->header.seq - first] == RX_ACK_TYPE_ACK) {
-               if (!tp->acked) {
+               if (!(tp->flags & RX_PKTFLAG_ACKED)) {
                    newAckCount++;
-                   tp->acked = 1;
+                   tp->flags |= RX_PKTFLAG_ACKED;
                }
                if (missing) {
                    nNacked++;
@@ -3418,12 +3418,12 @@ struct rx_packet *rxi_ReceiveAckPacket(call, np, istack)
                    call->nSoftAcked++;
                }
            } else {
-               tp->acked = 0;
+               tp->flags &= ~RX_PKTFLAG_ACKED;
                missing = 1;
            }
        }
        else {
-           tp->acked = 0;
+           tp->flags &= ~RX_PKTFLAG_ACKED;
            missing = 1;
        }
 
@@ -3432,7 +3432,7 @@ struct rx_packet *rxi_ReceiveAckPacket(call, np, istack)
         * ie, this should readjust the retransmit timer for all outstanding 
         * packets...  So we don't just retransmit when we should know better*/
 
-       if (!tp->acked && !clock_IsZero(&tp->retryTime)) {
+       if (!(tp->flags & RX_PKTFLAG_ACKED) && !clock_IsZero(&tp->retryTime)) {
          tp->retryTime = tp->timeSent;
          clock_Add(&tp->retryTime, &peer->timeout);
          /* shift by eight because one quarter-sec ~ 256 milliseconds */
@@ -3625,10 +3625,10 @@ struct rx_packet *rxi_ReceiveAckPacket(call, np, istack)
         * so we will retransmit as soon as the window permits*/
        for(acked = 0, queue_ScanBackwards(&call->tq, tp, nxp, rx_packet)) {
            if (acked) {
-               if (!tp->acked) {
+               if (!(tp->flags & RX_PKTFLAG_ACKED)) {
                    clock_Zero(&tp->retryTime);
                }
-           } else if (tp->acked) {
+           } else if (tp->flags & RX_PKTFLAG_ACKED) {
                acked = 1;
            }
        }
@@ -3938,7 +3938,7 @@ static void rxi_SetAcksInTransmitQueue(call)
      for (queue_Scan(&call->tq, p, tp, rx_packet)) {
         if (!p) 
             break;
-        p->acked = 1;
+        p->flags |= RX_PKTFLAG_ACKED;
         someAcked = 1;
      }
      if (someAcked) {
@@ -3975,7 +3975,7 @@ void rxi_ClearTransmitQueue(call, force)
        for (queue_Scan(&call->tq, p, tp, rx_packet)) {
          if (!p) 
             break;
-         p->acked = 1;
+         p->flags |= RX_PKTFLAG_ACKED;
          someAcked = 1;
        }
        if (someAcked) {
@@ -4628,7 +4628,7 @@ static void rxi_SendXmitList(call, list, len, istack, now, retryTime, resending)
        /* Does the current packet force us to flush the current list? */
        if (cnt > 0
            && (list[i]->header.serial
-               || list[i]->acked
+               || (list[i]->flags & RX_PKTFLAG_ACKED)
                || list[i]->length > RX_JUMBOBUFFERSIZE)) {
            if (lastCnt > 0) {
                rxi_SendList(call, lastP, lastCnt, istack, 1, now, retryTime, resending);
@@ -4644,7 +4644,7 @@ static void rxi_SendXmitList(call, list, len, istack, now, retryTime, resending)
        }
        /* Add the current packet to the list if it hasn't been acked.
         * Otherwise adjust the list pointer to skip the current packet.  */
-       if (!list[i]->acked) {
+       if (!(list[i]->flags & RX_PKTFLAG_ACKED)) {
            cnt++;
            /* Do we need to flush the list? */
            if (cnt >= (int)peer->maxDgramPackets
@@ -4684,7 +4684,7 @@ static void rxi_SendXmitList(call, list, len, istack, now, retryTime, resending)
         * an acked packet. Since we always send retransmissions
         * in a separate packet, we only need to check the first
         * packet in the list */
-       if (cnt > 0 && !listP[0]->acked) {
+       if (cnt > 0 && !(listP[0]->flags & RX_PKTFLAG_ACKED)) {
            morePackets = 1;
        }
        if (lastCnt > 0) {
@@ -4789,7 +4789,7 @@ void rxi_Start(event, call, istack)
         * than recovery rates.
         */
        for(queue_Scan(&call->tq, p, nxp, rx_packet)) {
-           if (!p->acked) {
+           if (!(p->flags & RX_PKTFLAG_ACKED)) {
                clock_Zero(&p->retryTime);
            }
        }
@@ -4852,14 +4852,14 @@ void rxi_Start(event, call, istack)
             /* Only send one packet during fast recovery */
             break;
          }
-         if ((p->header.flags == RX_FREE_PACKET) ||
+         if ((p->flags & RX_PKTFLAG_FREE) ||
              (!queue_IsEnd(&call->tq, nxp)
-              && (nxp->header.flags == RX_FREE_PACKET)) ||
+              && (nxp->flags & RX_PKTFLAG_FREE)) ||
              (p == (struct rx_packet *)&rx_freePacketQueue) ||
              (nxp == (struct rx_packet *)&rx_freePacketQueue)) {
              osi_Panic("rxi_Start: xmit queue clobbered");
          }
-         if (p->acked) {
+         if (p->flags & RX_PKTFLAG_ACKED) {
            MUTEX_ENTER(&rx_stats_mutex);
            rx_stats.ignoreAckedPacket++;
            MUTEX_EXIT(&rx_stats_mutex);
@@ -4942,7 +4942,7 @@ void rxi_Start(event, call, istack)
             * the transmit queue.
             */
            for (missing = 0, queue_Scan(&call->tq, p, nxp, rx_packet)) {
-               if (p->header.seq < call->tfirst && p->acked) {
+               if (p->header.seq < call->tfirst && (p->flags & RX_PKTFLAG_ACKED)) {
                    queue_Remove(p);
                    rxi_FreePacket(p);
                }
@@ -4978,7 +4978,7 @@ void rxi_Start(event, call, istack)
                break;
            }
 
-           if (!p->acked && !clock_IsZero(&p->retryTime)) {
+           if (!(p->flags & RX_PKTFLAG_ACKED) && !clock_IsZero(&p->retryTime)) {
                haveEvent = 1;
                retryTime = p->retryTime;
                break;
index 602ed5d..b248117 100644 (file)
@@ -270,8 +270,9 @@ static struct rx_packet * allocCBuf(int class)
   rx_nFreePackets--;
   c = queue_First(&rx_freePacketQueue, rx_packet);
   queue_Remove(c);
-  if (c->header.flags != RX_FREE_PACKET)
+  if (!(c->flags & RX_PKTFLAG_FREE))
     osi_Panic("rxi_AllocPacket: packet not free\n");
+  c->flags &= ~RX_PKTFLAG_FREE;
   c->header.flags = 0;
   
 #ifdef KERNEL
@@ -375,7 +376,7 @@ void rxi_MorePackets(int apackets)
     p->wirevec[0].iov_len  = RX_HEADER_SIZE;
     p->wirevec[1].iov_base = (char *) (p->localdata);
     p->wirevec[1].iov_len  = RX_FIRSTBUFFERSIZE;
-    p->header.flags = RX_FREE_PACKET;
+    p->flags |= RX_PKTFLAG_FREE;
     p->niovecs = 2;
     
     queue_Append(&rx_freePacketQueue, p);
@@ -410,7 +411,7 @@ void rxi_MorePacketsNoLock(int apackets)
     p->wirevec[0].iov_len  = RX_HEADER_SIZE;
     p->wirevec[1].iov_base = (char *) (p->localdata);
     p->wirevec[1].iov_len  = RX_FIRSTBUFFERSIZE;
-    p->header.flags = RX_FREE_PACKET;
+    p->flags |= RX_PKTFLAG_FREE;
     p->niovecs = 2;
     
     queue_Append(&rx_freePacketQueue, p);
@@ -457,10 +458,10 @@ void rxi_FreePacketNoLock(struct rx_packet *p)
 {
   dpf(("Free %x\n", p));
 
-  if (p->header.flags & RX_FREE_PACKET)
+  if (p->flags & RX_PKTFLAG_FREE)
     osi_Panic("rxi_FreePacketNoLock: packet already free\n");
   rx_nFreePackets++;
-  p->header.flags = RX_FREE_PACKET;
+  p->flags |= RX_PKTFLAG_FREE;
   queue_Append(&rx_freePacketQueue, p);
 }
 
@@ -624,12 +625,13 @@ struct rx_packet *rxi_AllocPacketNoLock(class)
   
   rx_nFreePackets--;
   p = queue_First(&rx_freePacketQueue, rx_packet);
-  if (p->header.flags != RX_FREE_PACKET)
+  if (!(p->flags & RX_PKTFLAG_FREE))
     osi_Panic("rxi_AllocPacket: packet not free\n");
   
   dpf(("Alloc %x, class %d\n", p, class));
   
   queue_Remove(p);
+  p->flags &= ~RX_PKTFLAG_FREE;
   p->header.flags = 0;
   
   /* have to do this here because rx_FlushWrite fiddles with the iovs in
@@ -1878,7 +1880,7 @@ void rxi_PrepareSendPacket(call, p, last)
     int i, j;
     ssize_t len;       /* len must be a signed type; it can go negative */
 
-    p->acked = 0;
+    p->flags &= ~RX_PKTFLAG_ACKED;
     p->header.cid = (conn->cid | call->channel);
     p->header.serviceId = conn->serviceId;
     p->header.securityIndex = conn->securityIndex;
index 4c5e218..b77cffe 100644 (file)
                                     * the receiver should be greater than
                                      * this one, rather than a resend of an
                                     * earlier sequence number */
-#define        RX_FREE_PACKET          16      /* Unallocated to a call */
 #define RX_SLOW_START_OK       32  /* Set this flag in an ack packet to
                                     * inform the sender that slow start is
                                     * supported by the receiver. */
 #define        RX_PRESET_FLAGS         (RX_CLIENT_INITIATED | RX_LAST_PACKET)
 
 
+/*
+ * Flags for the packet structure itself, housekeeping for the
+ * most part.  These live in rx_packet->flags.
+ */
+#define        RX_PKTFLAG_ACKED        0x01
+#define        RX_PKTFLAG_FREE         0x02
+
+
 /* The rx part of the header of a packet, in host form */
 struct rx_header {
     afs_uint32 epoch;  /* Start time of client process */
@@ -245,7 +252,7 @@ struct rx_packet {
     unsigned int niovecs;
     struct iovec wirevec[RX_MAXWVECS+1];       /* the new form of the packet */
     
-    u_char acked;      /* This packet has been *tentatively* acknowledged */
+    u_char flags;                  /* Flags for local state of this packet */
     u_char backoff;                 /* for multiple re-sends */
     u_short length;                /* Data length */
     /* NT port relies on the fact that the next two are physically adjacent.