|
|
/*++
Copyright (c) 1999-2000 Microsoft Corporation
Module Name:
ipr9x.c
Abstract:
This file contains the implementation of IP Receive buffer list manager. On Windows ME this is done to avoid fragmenting the non-paged pool when receive buffers are not pre-posted by AFVXD.
Author:
Scott Holden (sholden) 30-Apr-2000
--*/
#include "precomp.h"
#include "addr.h"
#include "tcp.h"
#include "tcb.h"
#include "tcprcv.h"
#include "tcpsend.h"
#include "tcpconn.h"
#include "tcpdeliv.h"
#include "tlcommon.h"
#include "tcpipbuf.h"
#include "pplasl.h"
#include "mdl2ndis.h"
HANDLE TcpIprDataPoolSmall = NULL; HANDLE TcpIprDataPoolMedium = NULL; HANDLE TcpIprDataPoolLarge = NULL;
#if DBG
ULONG TcpIprAllocs = 0; ULONG TcpIprFrees = 0; ULONG TcpIprAllocMisses = 0; #endif // DBG
//
// The three buffer pool sizes are based on MTU. 576 for PPP, 1500 for ethernet,
// and 8K+ for loopback and ATM. Since for 8K buffers we really need a little
// more than 8K, we will allocate a full three pages
//
#define SMALL_TCP_IPR_BUFFER_SIZE (sizeof(IPRcvBuf) + sizeof(HANDLE) + 576)
#define MEDIUM_TCP_IPR_BUFFER_SIZE (sizeof(IPRcvBuf) + sizeof(HANDLE) + 1500)
#define LARGE_TCP_IPR_BUFFER_SIZE (3 * 4096)
//* UnInitTcpIprPools - Destroys TCP IPRcvBuffer lookaside lists.
//
// Uninitializes the lookasides lists for TCP buffered data.
//
// Input: None.
//
// Returns: None.
//
VOID UnInitTcpIprPools(VOID) { PplDestroyPool(TcpIprDataPoolSmall); PplDestroyPool(TcpIprDataPoolMedium); PplDestroyPool(TcpIprDataPoolLarge); }
//* InitTcpIprPools - Initializes TCP IPRcvBuffer lookaside lists.
//
// Initializes the lookaside lists for buffer data.
//
// Input: None.
//
// Returns: TRUE, if successful, else FALSE.
//
BOOLEAN InitTcpIprPools(VOID) { BOOLEAN Status = TRUE;
TcpIprDataPoolSmall = PplCreatePool(NULL, NULL, 0, SMALL_TCP_IPR_BUFFER_SIZE, 'BPCT', 512);
if (TcpIprDataPoolSmall == NULL) { Status = FALSE; goto done; }
TcpIprDataPoolMedium = PplCreatePool(NULL, NULL, 0, MEDIUM_TCP_IPR_BUFFER_SIZE, 'BPCT', 256);
if (TcpIprDataPoolMedium == NULL) { Status = FALSE; goto done; }
TcpIprDataPoolLarge = PplCreatePool(NULL, NULL, 0, LARGE_TCP_IPR_BUFFER_SIZE, 'BPCT', 64);
if (TcpIprDataPoolLarge == NULL) { Status = FALSE; }
done:
if (Status == FALSE) { UnInitTcpIprPools(); }
return (Status); }
//* AllocTcpIpr - Allocates the IPRcvBuffer from lookaside lists.
//
// A utility routine to allocate a TCP owned IPRcvBuffer. This routine
// attempts to allocate the RB from an appropriate lookaside list, el
//
// Input: BufferSize - Size of data to buffer.
//
// Returns: Pointer to allocated IPR.
//
IPRcvBuf * AllocTcpIpr(ULONG BufferSize, ULONG Tag) { PCHAR Buffer; IPRcvBuf *Ipr = NULL; LOGICAL FromList = FALSE; ULONG AllocateSize; HANDLE BufferPool = NULL; ULONG Depth;
// Real size that we need.
AllocateSize = BufferSize + sizeof(HANDLE) + sizeof(IPRcvBuf);
if (AllocateSize <= LARGE_TCP_IPR_BUFFER_SIZE) { //
// Pick the buffer pool to allocate from.
//
if (AllocateSize <= SMALL_TCP_IPR_BUFFER_SIZE) { BufferPool = TcpIprDataPoolSmall; } else if (AllocateSize <= MEDIUM_TCP_IPR_BUFFER_SIZE) { BufferPool = TcpIprDataPoolMedium; } else { BufferPool = TcpIprDataPoolLarge; }
Buffer = PplAllocate(BufferPool, &FromList);
} else { //
// Allocate from NP pool.
//
Buffer = CTEAllocMemLow(AllocateSize, Tag); } if (Buffer == NULL) { goto done; } #if DBG
if (FromList == FALSE) { InterlockedIncrement(&TcpIprAllocMisses); } #endif // DBG
// Store buffer pool so we know how to free the buffer.
*((HANDLE *)Buffer) = BufferPool;
// Get IPR.
Ipr = (IPRcvBuf *) (Buffer + sizeof(HANDLE));
// Set up IPR fields appropriately.
Ipr->ipr_owner = IPR_OWNER_TCP; Ipr->ipr_next = NULL; Ipr->ipr_buffer = (PCHAR) Ipr + sizeof(IPRcvBuf); Ipr->ipr_size = BufferSize;
#if DBG
InterlockedIncrement(&TcpIprAllocs); #endif // DBG
done:
return (Ipr); }
//* FreeTcpIpr - Frees the IPRcvBuffer to the correct lookaside list.
//
// A utility routine to free a TCP owned IPRcvBuffer.
//
// Input: Ipr - Pointer the RB.
//
// Returns: None.
//
VOID FreeTcpIpr(IPRcvBuf *Ipr) { HANDLE BufferPool; PCHAR Buffer;
// Get real start of buffer.
Buffer = (PCHAR) Ipr - sizeof(HANDLE);
// Get the pool handle.
BufferPool = *((HANDLE *) Buffer);
if (BufferPool) { PplFree(BufferPool, Buffer); } else { CTEFreeMem(Buffer); }
#if DBG
InterlockedIncrement(&TcpIprFrees); #endif // DBG
return; }
|