From 5f00e54cfa6105f8018366ec113d69ae2cdb4e0e Mon Sep 17 00:00:00 2001 From: Tom Keiser Date: Thu, 1 Dec 2005 04:00:39 +0000 Subject: [PATCH] STABLE14-freepackets-cbuf-leak-20051130 FIXES 23143 at least i'm guessing it fixes that one fix memory leak for multilevel packet queue stuff (cherry picked from commit 421e063d9b6500299b5e02b999b22c01dcc7c496) --- src/rx/rx_packet.c | 61 +++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 55 insertions(+), 6 deletions(-) diff --git a/src/rx/rx_packet.c b/src/rx/rx_packet.c index 33eed2402..4963667e4 100644 --- a/src/rx/rx_packet.c +++ b/src/rx/rx_packet.c @@ -114,6 +114,9 @@ static void rxi_SendDebugPacket(struct rx_packet *apacket, osi_socket asocket, afs_int32 ahost, short aport, afs_int32 istack); +static int rxi_FreeDataBufsToQueue(struct rx_packet *p, int first, + struct rx_queue * q); + /* some rules about packets: * 1. When a packet is allocated, the final iov_buf contains room for * a security trailer, but iov_len masks that fact. If the security @@ -381,14 +384,22 @@ rxi_FreePackets(int num_pkts, struct rx_queue * q) register struct rx_packet *c, *nc; SPLVAR; + osi_Assert(num_pkts >= 0); + RX_TS_INFO_GET(rx_ts_info); + if (!num_pkts) { - queue_Count(q, c, nc, rx_packet, num_pkts); - if (!num_pkts) - return 0; + for (queue_Scan(q, c, nc, rx_packet), num_pkts++) { + rxi_FreeDataBufsTSFPQ(c, 1, 0); + } + } else { + for (queue_Scan(q, c, nc, rx_packet)) { + rxi_FreeDataBufsTSFPQ(c, 1, 0); + } } - RX_TS_INFO_GET(rx_ts_info); - RX_TS_FPQ_CHECKIN2(rx_ts_info, num_pkts, q); + if (num_pkts) { + RX_TS_FPQ_CHECKIN2(rx_ts_info, num_pkts, q); + } if (rx_ts_info->_FPQ.len > rx_TSFPQLocalMax) { NETPRI; @@ -410,26 +421,43 @@ rxi_FreePackets(int num_pkts, struct rx_queue * q) int rxi_FreePackets(int num_pkts, struct rx_queue *q) { + struct rx_queue cbs; register struct rx_packet *p, *np; + int qlen = 0; SPLVAR; + osi_Assert(num_pkts >= 0); + queue_Init(&cbs); + if (!num_pkts) { for (queue_Scan(q, p, np, rx_packet), num_pkts++) { + if (p->niovecs > 2) { + qlen += rxi_FreeDataBufsToQueue(p, 2, &cbs); + } RX_FPQ_MARK_FREE(p); } if (!num_pkts) return 0; } else { for (queue_Scan(q, p, np, rx_packet)) { + if (p->niovecs > 2) { + qlen += rxi_FreeDataBufsToQueue(p, 2, &cbs); + } RX_FPQ_MARK_FREE(p); } } + if (qlen) { + queue_SpliceAppend(q, &cbs); + qlen += num_pkts; + } else + qlen = num_pkts; + NETPRI; MUTEX_ENTER(&rx_freePktQ_lock); queue_SpliceAppend(&rx_freePacketQueue, q); - rx_nFreePackets += num_pkts; + rx_nFreePackets += qlen; /* Wakeup anyone waiting for packets */ rxi_PacketsUnWait(); @@ -777,6 +805,27 @@ rxi_FreePacketTSFPQ(struct rx_packet *p, int flush_global) } #endif /* RX_ENABLE_TSFPQ */ +/* free continuation buffers off a packet into a queue of buffers */ +static int +rxi_FreeDataBufsToQueue(struct rx_packet *p, int first, struct rx_queue * q) +{ + struct iovec *iov; + int count = 0; + + if (first < 2) + first = 2; + for (; first < p->niovecs; first++, count++) { + iov = &p->wirevec[first]; + if (!iov->iov_base) + osi_Panic("rxi_PacketIOVToQueue: unexpected NULL iov"); + queue_Append(q, RX_CBUF_TO_PACKET(iov->iov_base, p)); + } + p->length = 0; + p->niovecs = 0; + + return count; +} + int rxi_FreeDataBufsNoLock(struct rx_packet *p, int first) { -- 2.39.5