MUTEX_INIT(&rx_rpc_stats, "rx_rpc_stats", MUTEX_DEFAULT, 0);
MUTEX_INIT(&rx_freePktQ_lock, "rx_freePktQ_lock", MUTEX_DEFAULT, 0);
+ MUTEX_INIT(&rx_mallocedPktQ_lock, "rx_mallocedPktQ_lock", MUTEX_DEFAULT,
+ 0);
+
#ifdef RX_ENABLE_LOCKS
#ifdef RX_LOCKS_DB
rxdb_init();
MUTEX_INIT(&rx_connHashTable_lock, "rx_connHashTable_lock", MUTEX_DEFAULT,
0);
MUTEX_INIT(&rx_serverPool_lock, "rx_serverPool_lock", MUTEX_DEFAULT, 0);
+ MUTEX_INIT(&rx_mallocedPktQ_lock, "rx_mallocedPktQ_lock", MUTEX_DEFAULT,
+ 0);
+
#if defined(AFS_HPUX110_ENV)
if (!uniprocessor)
rx_sleepLock = alloc_spinlock(LAST_HELD_ORDER - 10, "rx_sleepLock");
opr_queue_Init(&rx_freePacketQueue);
rxi_NeedMorePackets = FALSE;
rx_nPackets = 0; /* rx_nPackets is managed by rxi_MorePackets* */
+ opr_queue_Init(&rx_mallocedPacketQueue);
/* enforce a minimum number of allocated packets */
if (rx_extraPackets < rxi_nSendFrags * rx_maxSendWindow)
rx_hashTableSize * sizeof(struct rx_connection *));
UNPIN(rx_peerHashTable, rx_hashTableSize * sizeof(struct rx_peer *));
- rxi_FreeAllPackets();
-
MUTEX_ENTER(&rx_quota_mutex);
rxi_dataQuota = RX_MAX_QUOTA;
rxi_availProcs = rxi_totalMin = rxi_minDeficit = 0;
EXT afs_kmutex_t rx_freePktQ_lock;
#endif /* RX_ENABLE_LOCKS */
+/*!
+ * \brief Queue of allocated packets.
+ *
+ * This queue is used to keep track of the blocks of allocated packets.
+ * This information is used when afs is being unmounted and the memory
+ * used by those packets needs to be released.
+ */
+EXT struct opr_queue rx_mallocedPacketQueue;
+#ifdef RX_ENABLE_LOCKS
+EXT afs_kmutex_t rx_mallocedPktQ_lock;
+#endif /* RX_ENABLE_LOCKS */
+
#if defined(AFS_PTHREAD_ENV) && !defined(KERNEL)
#define RX_ENABLE_TSFPQ
EXT int rx_TSFPQGlobSize GLOBALSINIT(3); /* number of packets to transfer between global and local queues in one op */
#include "rx_conn.h"
#include "rx_call.h"
+/*!
+ * \brief structure used to keep track of allocated packets
+ */
+struct rx_mallocedPacket {
+ struct opr_queue entry; /*!< chained using opr_queue */
+ struct rx_packet *addr; /*!< address of the first element */
+ afs_uint32 size; /*!< array size in bytes */
+};
+
#ifdef RX_LOCKS_DB
/* rxdb_fileID is used to identify the lock location, along with line#. */
static int rxdb_fileID = RXDB_FILE_RX_PACKET;
return nb;
}
+/**
+ * Register allocated packets.
+ *
+ * @param[in] addr array of packets
+ * @param[in] npkt number of packets
+ *
+ * @return none
+ */
+static void
+registerPackets(struct rx_packet *addr, afs_uint32 npkt)
+{
+ struct rx_mallocedPacket *mp;
+
+ mp = osi_Alloc(sizeof(*mp));
+
+ osi_Assert(mp != NULL);
+ memset(mp, 0, sizeof(*mp));
+
+ mp->addr = addr;
+ mp->size = npkt * sizeof(struct rx_packet);
+ osi_Assert(npkt <= MAX_AFS_UINT32 / sizeof(struct rx_packet));
+
+ MUTEX_ENTER(&rx_mallocedPktQ_lock);
+ opr_queue_Append(&rx_mallocedPacketQueue, &mp->entry);
+ MUTEX_EXIT(&rx_mallocedPktQ_lock);
+}
+
/* Add more packet buffers */
#ifdef RX_ENABLE_TSFPQ
void
getme = apackets * sizeof(struct rx_packet);
p = osi_Alloc(getme);
osi_Assert(p);
+ registerPackets(p, apackets);
PIN(p, getme); /* XXXXX */
memset(p, 0, getme);
getme = apackets * sizeof(struct rx_packet);
p = osi_Alloc(getme);
osi_Assert(p);
+ registerPackets(p, apackets);
PIN(p, getme); /* XXXXX */
memset(p, 0, getme);
getme = apackets * sizeof(struct rx_packet);
p = osi_Alloc(getme);
+ registerPackets(p, apackets);
PIN(p, getme); /* XXXXX */
memset(p, 0, getme);
}
} while(p == NULL);
memset(p, 0, getme);
+ registerPackets(p, apackets);
#ifdef RX_ENABLE_TSFPQ
RX_TS_INFO_GET(rx_ts_info);
void
rxi_FreeAllPackets(void)
{
- /* must be called at proper interrupt level, etcetera */
- /* MTUXXX need to free all Packets */
- osi_Free(rx_mallocedP,
- (rx_maxReceiveWindow + 2) * sizeof(struct rx_packet));
- UNPIN(rx_mallocedP, (rx_maxReceiveWindow + 2) * sizeof(struct rx_packet));
+ struct rx_mallocedPacket *mp;
+
+ MUTEX_ENTER(&rx_mallocedPktQ_lock);
+
+ while (!opr_queue_IsEmpty(&rx_mallocedPacketQueue)) {
+ mp = opr_queue_First(&rx_mallocedPacketQueue,
+ struct rx_mallocedPacket, entry);
+ opr_queue_Remove(&mp->entry);
+ osi_Free(mp->addr, mp->size);
+ UNPIN(mp->addr, mp->size);
+ osi_Free(mp, sizeof(*mp));
+ }
+ MUTEX_EXIT(&rx_mallocedPktQ_lock);
}
#ifdef RX_ENABLE_TSFPQ