MAXPATHLEN is 1024, which means NdisOpenFile() and ndis_find_sym() were
both consuming 1K of stack space. This is unfriendly. Allocate the buffers off the heap instead. It's a little slower, but these aren't performance critical routines. Also, add a spinlock to NdisAllocatePacketPool(), NdisAllocatePacket(), NdisFreePacketPool() and NdisFreePacket(). The pool is maintained as a linked list. I don't know for a fact that it can be corrupted, but why take chances.
This commit is contained in:
parent
70037e98c4
commit
7d962e5cc5
@ -1161,6 +1161,7 @@ struct ndis_packet {
|
|||||||
void *np_softc;
|
void *np_softc;
|
||||||
void *np_m0;
|
void *np_m0;
|
||||||
int np_txidx;
|
int np_txidx;
|
||||||
|
kspin_lock np_lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct ndis_packet ndis_packet;
|
typedef struct ndis_packet ndis_packet;
|
||||||
|
@ -1660,6 +1660,7 @@ NdisAllocatePacketPool(status, pool, descnum, protrsvdlen)
|
|||||||
}
|
}
|
||||||
|
|
||||||
cur = (ndis_packet *)*pool;
|
cur = (ndis_packet *)*pool;
|
||||||
|
KeInitializeSpinLock(&cur->np_lock);
|
||||||
cur->np_private.npp_flags = 0x1; /* mark the head of the list */
|
cur->np_private.npp_flags = 0x1; /* mark the head of the list */
|
||||||
cur->np_private.npp_totlen = 0; /* init deletetion flag */
|
cur->np_private.npp_totlen = 0; /* init deletetion flag */
|
||||||
for (i = 0; i < (descnum + NDIS_POOL_EXTRA); i++) {
|
for (i = 0; i < (descnum + NDIS_POOL_EXTRA); i++) {
|
||||||
@ -1688,10 +1689,15 @@ NdisPacketPoolUsage(pool)
|
|||||||
ndis_handle pool;
|
ndis_handle pool;
|
||||||
{
|
{
|
||||||
ndis_packet *head;
|
ndis_packet *head;
|
||||||
|
uint8_t irql;
|
||||||
|
uint32_t cnt;
|
||||||
|
|
||||||
head = (ndis_packet *)pool;
|
head = (ndis_packet *)pool;
|
||||||
|
KeAcquireSpinLock(&head->np_lock, &irql);
|
||||||
|
cnt = head->np_private.npp_count;
|
||||||
|
KeReleaseSpinLock(&head->np_lock, irql);
|
||||||
|
|
||||||
return(head->np_private.npp_count);
|
return(cnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
__stdcall void
|
__stdcall void
|
||||||
@ -1699,19 +1705,24 @@ NdisFreePacketPool(pool)
|
|||||||
ndis_handle pool;
|
ndis_handle pool;
|
||||||
{
|
{
|
||||||
ndis_packet *head;
|
ndis_packet *head;
|
||||||
|
uint8_t irql;
|
||||||
|
|
||||||
head = pool;
|
head = pool;
|
||||||
|
|
||||||
/* Mark this pool as 'going away.' */
|
/* Mark this pool as 'going away.' */
|
||||||
|
|
||||||
|
KeAcquireSpinLock(&head->np_lock, &irql);
|
||||||
head->np_private.npp_totlen = 1;
|
head->np_private.npp_totlen = 1;
|
||||||
|
|
||||||
/* If there are no buffers loaned out, destroy the pool. */
|
/* If there are no buffers loaned out, destroy the pool. */
|
||||||
|
|
||||||
if (head->np_private.npp_count == 0)
|
if (head->np_private.npp_count == 0) {
|
||||||
|
KeReleaseSpinLock(&head->np_lock, irql);
|
||||||
free(pool, M_DEVBUF);
|
free(pool, M_DEVBUF);
|
||||||
else
|
} else {
|
||||||
printf("NDIS: buggy driver deleting active packet pool!\n");
|
printf("NDIS: buggy driver deleting active packet pool!\n");
|
||||||
|
KeReleaseSpinLock(&head->np_lock, irql);
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -1723,11 +1734,14 @@ NdisAllocatePacket(status, packet, pool)
|
|||||||
ndis_handle pool;
|
ndis_handle pool;
|
||||||
{
|
{
|
||||||
ndis_packet *head, *pkt;
|
ndis_packet *head, *pkt;
|
||||||
|
uint8_t irql;
|
||||||
|
|
||||||
head = (ndis_packet *)pool;
|
head = (ndis_packet *)pool;
|
||||||
|
KeAcquireSpinLock(&head->np_lock, &irql);
|
||||||
|
|
||||||
if (head->np_private.npp_flags != 0x1) {
|
if (head->np_private.npp_flags != 0x1) {
|
||||||
*status = NDIS_STATUS_FAILURE;
|
*status = NDIS_STATUS_FAILURE;
|
||||||
|
KeReleaseSpinLock(&head->np_lock, irql);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1738,6 +1752,7 @@ NdisAllocatePacket(status, packet, pool)
|
|||||||
|
|
||||||
if (head->np_private.npp_totlen) {
|
if (head->np_private.npp_totlen) {
|
||||||
*status = NDIS_STATUS_FAILURE;
|
*status = NDIS_STATUS_FAILURE;
|
||||||
|
KeReleaseSpinLock(&head->np_lock, irql);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1745,6 +1760,7 @@ NdisAllocatePacket(status, packet, pool)
|
|||||||
|
|
||||||
if (pkt == NULL) {
|
if (pkt == NULL) {
|
||||||
*status = NDIS_STATUS_RESOURCES;
|
*status = NDIS_STATUS_RESOURCES;
|
||||||
|
KeReleaseSpinLock(&head->np_lock, irql);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1771,6 +1787,8 @@ NdisAllocatePacket(status, packet, pool)
|
|||||||
head->np_private.npp_count++;
|
head->np_private.npp_count++;
|
||||||
*status = NDIS_STATUS_SUCCESS;
|
*status = NDIS_STATUS_SUCCESS;
|
||||||
|
|
||||||
|
KeReleaseSpinLock(&head->np_lock, irql);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1779,13 +1797,18 @@ NdisFreePacket(packet)
|
|||||||
ndis_packet *packet;
|
ndis_packet *packet;
|
||||||
{
|
{
|
||||||
ndis_packet *head;
|
ndis_packet *head;
|
||||||
|
uint8_t irql;
|
||||||
|
|
||||||
if (packet == NULL || packet->np_private.npp_pool == NULL)
|
if (packet == NULL || packet->np_private.npp_pool == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
head = packet->np_private.npp_pool;
|
head = packet->np_private.npp_pool;
|
||||||
if (head->np_private.npp_flags != 0x1)
|
KeAcquireSpinLock(&head->np_lock, &irql);
|
||||||
|
|
||||||
|
if (head->np_private.npp_flags != 0x1) {
|
||||||
|
KeReleaseSpinLock(&head->np_lock, irql);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
packet->np_private.npp_head = head->np_private.npp_head;
|
packet->np_private.npp_head = head->np_private.npp_head;
|
||||||
head->np_private.npp_head = (ndis_buffer *)packet;
|
head->np_private.npp_head = (ndis_buffer *)packet;
|
||||||
@ -1796,8 +1819,11 @@ NdisFreePacket(packet)
|
|||||||
* no more packets outstanding, nuke the pool.
|
* no more packets outstanding, nuke the pool.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (head->np_private.npp_totlen && head->np_private.npp_count == 0)
|
if (head->np_private.npp_totlen && head->np_private.npp_count == 0) {
|
||||||
|
KeReleaseSpinLock(&head->np_lock, irql);
|
||||||
free(head, M_DEVBUF);
|
free(head, M_DEVBUF);
|
||||||
|
} else
|
||||||
|
KeReleaseSpinLock(&head->np_lock, irql);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -2556,14 +2582,20 @@ ndis_find_sym(lf, filename, suffix, sym)
|
|||||||
char *suffix;
|
char *suffix;
|
||||||
caddr_t *sym;
|
caddr_t *sym;
|
||||||
{
|
{
|
||||||
char fullsym[MAXPATHLEN];
|
char *fullsym;
|
||||||
char *suf;
|
char *suf;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
bzero(fullsym, sizeof(fullsym));
|
fullsym = ExAllocatePoolWithTag(NonPagedPool, MAXPATHLEN, 0);
|
||||||
strcpy(fullsym, filename);
|
if (fullsym == NULL)
|
||||||
if (strlen(filename) < 4)
|
return(ENOMEM);
|
||||||
|
|
||||||
|
bzero(fullsym, MAXPATHLEN);
|
||||||
|
strncpy(fullsym, filename, MAXPATHLEN);
|
||||||
|
if (strlen(filename) < 4) {
|
||||||
|
ExFreePool(fullsym);
|
||||||
return(EINVAL);
|
return(EINVAL);
|
||||||
|
}
|
||||||
|
|
||||||
/* If the filename has a .ko suffix, strip if off. */
|
/* If the filename has a .ko suffix, strip if off. */
|
||||||
suf = fullsym + (strlen(filename) - 3);
|
suf = fullsym + (strlen(filename) - 3);
|
||||||
@ -2578,6 +2610,7 @@ ndis_find_sym(lf, filename, suffix, sym)
|
|||||||
}
|
}
|
||||||
strcat(fullsym, suffix);
|
strcat(fullsym, suffix);
|
||||||
*sym = linker_file_lookup_symbol(lf, fullsym, 0);
|
*sym = linker_file_lookup_symbol(lf, fullsym, 0);
|
||||||
|
ExFreePool(fullsym);
|
||||||
if (*sym == 0)
|
if (*sym == 0)
|
||||||
return(ENOENT);
|
return(ENOENT);
|
||||||
|
|
||||||
@ -2600,14 +2633,14 @@ NdisOpenFile(status, filehandle, filelength, filename, highestaddr)
|
|||||||
struct vattr vat;
|
struct vattr vat;
|
||||||
struct vattr *vap = &vat;
|
struct vattr *vap = &vat;
|
||||||
ndis_fh *fh;
|
ndis_fh *fh;
|
||||||
char path[MAXPATHLEN];
|
char *path;
|
||||||
linker_file_t head, lf;
|
linker_file_t head, lf;
|
||||||
caddr_t kldstart, kldend;
|
caddr_t kldstart, kldend;
|
||||||
|
|
||||||
ndis_unicode_to_ascii(filename->us_buf,
|
ndis_unicode_to_ascii(filename->us_buf,
|
||||||
filename->us_len, &afilename);
|
filename->us_len, &afilename);
|
||||||
|
|
||||||
fh = malloc(sizeof(ndis_fh), M_TEMP, M_NOWAIT);
|
fh = ExAllocatePoolWithTag(NonPagedPool, sizeof(ndis_fh), 0);
|
||||||
if (fh == NULL) {
|
if (fh == NULL) {
|
||||||
*status = NDIS_STATUS_RESOURCES;
|
*status = NDIS_STATUS_RESOURCES;
|
||||||
return;
|
return;
|
||||||
@ -2666,7 +2699,13 @@ NdisOpenFile(status, filehandle, filelength, filename, highestaddr)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(path, "%s/%s", ndis_filepath, afilename);
|
path = ExAllocatePoolWithTag(NonPagedPool, MAXPATHLEN, 0);
|
||||||
|
if (path == NULL) {
|
||||||
|
*status = NDIS_STATUS_RESOURCES;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
snprintf(path, MAXPATHLEN, "%s/%s", ndis_filepath, afilename);
|
||||||
free(afilename, M_DEVBUF);
|
free(afilename, M_DEVBUF);
|
||||||
|
|
||||||
mtx_lock(&Giant);
|
mtx_lock(&Giant);
|
||||||
@ -2685,11 +2724,14 @@ NdisOpenFile(status, filehandle, filelength, filename, highestaddr)
|
|||||||
if (error) {
|
if (error) {
|
||||||
mtx_unlock(&Giant);
|
mtx_unlock(&Giant);
|
||||||
*status = NDIS_STATUS_FILE_NOT_FOUND;
|
*status = NDIS_STATUS_FILE_NOT_FOUND;
|
||||||
free(fh, M_TEMP);
|
ExFreePool(fh);
|
||||||
printf("NDIS: open file %s failed: %d\n", path, error);
|
printf("NDIS: open file %s failed: %d\n", path, error);
|
||||||
|
ExFreePool(path);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ExFreePool(path);
|
||||||
|
|
||||||
NDFREE(&nd, NDF_ONLY_PNBUF);
|
NDFREE(&nd, NDF_ONLY_PNBUF);
|
||||||
|
|
||||||
/* Get the file size. */
|
/* Get the file size. */
|
||||||
@ -2748,7 +2790,7 @@ NdisMapFile(status, mappedbuffer, filehandle)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fh->nf_map = malloc(fh->nf_maplen, M_DEVBUF, M_NOWAIT);
|
fh->nf_map = ExAllocatePoolWithTag(NonPagedPool, fh->nf_maplen, 0);
|
||||||
|
|
||||||
if (fh->nf_map == NULL) {
|
if (fh->nf_map == NULL) {
|
||||||
*status = NDIS_STATUS_RESOURCES;
|
*status = NDIS_STATUS_RESOURCES;
|
||||||
@ -2781,7 +2823,7 @@ NdisUnmapFile(filehandle)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (fh->nf_type == NDIS_FH_TYPE_VFS)
|
if (fh->nf_type == NDIS_FH_TYPE_VFS)
|
||||||
free(fh->nf_map, M_DEVBUF);
|
ExFreePool(fh->nf_map);
|
||||||
fh->nf_map = NULL;
|
fh->nf_map = NULL;
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -2800,7 +2842,7 @@ NdisCloseFile(filehandle)
|
|||||||
fh = (ndis_fh *)filehandle;
|
fh = (ndis_fh *)filehandle;
|
||||||
if (fh->nf_map != NULL) {
|
if (fh->nf_map != NULL) {
|
||||||
if (fh->nf_type == NDIS_FH_TYPE_VFS)
|
if (fh->nf_type == NDIS_FH_TYPE_VFS)
|
||||||
free(fh->nf_map, M_DEVBUF);
|
ExFreePool(fh->nf_map);
|
||||||
fh->nf_map = NULL;
|
fh->nf_map = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2814,7 +2856,7 @@ NdisCloseFile(filehandle)
|
|||||||
}
|
}
|
||||||
|
|
||||||
fh->nf_vp = NULL;
|
fh->nf_vp = NULL;
|
||||||
free(fh, M_DEVBUF);
|
ExFreePool(fh);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user