From 593e5a8c405685cf116a4d207bf6358343054fa9 Mon Sep 17 00:00:00 2001 From: Nickolai Zeldovich Date: Fri, 7 Sep 2001 21:47:57 +0000 Subject: [PATCH] rx-do-housekeeping-on-packets-with-new-flags-20010907 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 | 44 ++++++++++++++++++++++---------------------- src/rx/rx_packet.c | 16 +++++++++------- src/rx/rx_packet.h | 11 +++++++++-- 3 files changed, 40 insertions(+), 31 deletions(-) diff --git a/src/rx/rx.c b/src/rx/rx.c index 83f7eb4b7..c74472db3 100644 --- a/src/rx/rx.c +++ b/src/rx/rx.c @@ -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; diff --git a/src/rx/rx_packet.c b/src/rx/rx_packet.c index 602ed5d8c..b248117ff 100644 --- a/src/rx/rx_packet.c +++ b/src/rx/rx_packet.c @@ -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; diff --git a/src/rx/rx_packet.h b/src/rx/rx_packet.h index 4c5e21897..b77cffe39 100644 --- a/src/rx/rx_packet.h +++ b/src/rx/rx_packet.h @@ -151,7 +151,6 @@ * 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. */ @@ -164,6 +163,14 @@ #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. -- 2.39.5