mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-12-04 08:09:08 +00:00
Remove mbpool(9) now that it has no consumers.
mbpool existed to support NICs with memory interfaces and all remaining comsumers were removed earlier this year with NATM. Reviewed by: jhb Sponsored by: DARPA, AFRL Differential Revision: https://reviews.freebsd.org/D10513
This commit is contained in:
parent
b0900232b9
commit
39ed7f250a
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=324710
@ -38,6 +38,19 @@
|
||||
# xargs -n1 | sort | uniq -d;
|
||||
# done
|
||||
|
||||
# 20171017: Removal of mbpool(9)
|
||||
OLD_FILES+=usr/include/sys/mbpool.h
|
||||
OLD_FILES+=usr/share/man/man9/mbpool.9.gz
|
||||
OLD_FILES+=usr/share/man/man9/mbp_destroy.9.gz
|
||||
OLD_FILES+=usr/share/man/man9/mbp_alloc.9.gz
|
||||
OLD_FILES+=usr/share/man/man9/mbp_ext_free.9.gz
|
||||
OLD_FILES+=usr/share/man/man9/mbp_count.9.gz
|
||||
OLD_FILES+=usr/share/man/man9/mbp_card_free.9.gz
|
||||
OLD_FILES+=usr/share/man/man9/mbp_get_keep.9.gz
|
||||
OLD_FILES+=usr/share/man/man9/mbp_free.9.gz
|
||||
OLD_FILES+=usr/share/man/man9/mbp_get.9.gz
|
||||
OLD_FILES+=usr/share/man/man9/mbp_create.9.gz
|
||||
OLD_FILES+=usr/share/man/man9/mbp_sync.9.gz
|
||||
# 20171010: Remove libstand
|
||||
OLD_FILES+=usr/lib/libstand.a
|
||||
OLD_FILES+=usr/lib/libstand_p.a
|
||||
|
@ -184,7 +184,6 @@ MAN= accept_filter.9 \
|
||||
make_dev.9 \
|
||||
malloc.9 \
|
||||
mbchain.9 \
|
||||
mbpool.9 \
|
||||
mbuf.9 \
|
||||
mbuf_tags.9 \
|
||||
MD5.9 \
|
||||
@ -1162,16 +1161,6 @@ MLINKS+=mbchain.9 mb_detach.9 \
|
||||
mbchain.9 mb_put_uint8.9 \
|
||||
mbchain.9 mb_put_uio.9 \
|
||||
mbchain.9 mb_reserve.9
|
||||
MLINKS+=mbpool.9 mbp_alloc.9 \
|
||||
mbpool.9 mbp_card_free.9 \
|
||||
mbpool.9 mbp_count.9 \
|
||||
mbpool.9 mbp_create.9 \
|
||||
mbpool.9 mbp_destroy.9 \
|
||||
mbpool.9 mbp_ext_free.9 \
|
||||
mbpool.9 mbp_free.9 \
|
||||
mbpool.9 mbp_get.9 \
|
||||
mbpool.9 mbp_get_keep.9 \
|
||||
mbpool.9 mbp_sync.9
|
||||
MLINKS+=\
|
||||
mbuf.9 m_adj.9 \
|
||||
mbuf.9 m_align.9 \
|
||||
|
@ -1,262 +0,0 @@
|
||||
.\" Copyright (c) 2003
|
||||
.\" Fraunhofer Institute for Open Communication Systems (FhG Fokus).
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" Author: Hartmut Brandt <harti@FreeBSD.org>
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd September 27, 2017
|
||||
.Dt MBPOOL 9
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm mbpool
|
||||
.Nd "buffer pools for network interfaces"
|
||||
.Sh SYNOPSIS
|
||||
.In sys/types.h
|
||||
.In machine/bus.h
|
||||
.In sys/mbpool.h
|
||||
.Vt struct mbpool ;
|
||||
.Ft int
|
||||
.Fo mbp_create
|
||||
.Fa "struct mbpool **mbp" "const char *name" "bus_dma_tag_t dmat"
|
||||
.Fa "u_int max_pages" "size_t page_size" "size_t chunk_size"
|
||||
.Fc
|
||||
.Ft void
|
||||
.Fn mbp_destroy "struct mbpool *mbp"
|
||||
.Ft "void *"
|
||||
.Fn mbp_alloc "struct mbpool *mbp" "bus_addr_t *pa" "uint32_t *hp"
|
||||
.Ft void
|
||||
.Fn mbp_free "struct mbpool *mbp" "void *p"
|
||||
.Ft void
|
||||
.Fn mbp_ext_free "struct mbuf *"
|
||||
.Ft void
|
||||
.Fn mbp_card_free "struct mbpool *mbp"
|
||||
.Ft void
|
||||
.Fn mbp_count "struct mbpool *mbp" "u_int *used" "u_int *card" "u_int *free"
|
||||
.Ft "void *"
|
||||
.Fn mbp_get "struct mbpool *mbp" "uint32_t h"
|
||||
.Ft "void *"
|
||||
.Fn mbp_get_keep "struct mbpool *mbp" "uint32_t h"
|
||||
.Ft void
|
||||
.Fo mbp_sync
|
||||
.Fa "struct mbpool *mbp" "uint32_t h" "bus_addr_t off" "bus_size_t len"
|
||||
.Fa "u_int op"
|
||||
.Fc
|
||||
.Pp
|
||||
.Fn MODULE_DEPEND "your_module" "libmbpool" 1 1 1
|
||||
.Pp
|
||||
.Cd "options LIBMBPOOL"
|
||||
.Sh DESCRIPTION
|
||||
Mbuf pools are intended to help drivers for interface cards that need huge
|
||||
amounts of receive buffers, and additionally provides a mapping between these
|
||||
buffers and 32-bit handles.
|
||||
.Pp
|
||||
An example of these cards are the Fore/Marconi ForeRunnerHE cards.
|
||||
These
|
||||
employ up to 8 receive groups, each with two buffer pools, each of which
|
||||
can contain up to 8192.
|
||||
This gives a total maximum number of more than
|
||||
100000 buffers.
|
||||
Even with a more moderate configuration the card eats several
|
||||
thousand buffers.
|
||||
Each of these buffers must be mapped for DMA.
|
||||
While for
|
||||
machines without an IOMMU and with lesser than 4GByte memory this is not
|
||||
a problem, for other machines this may quickly eat up all available IOMMU
|
||||
address space and/or bounce buffers.
|
||||
On sparc64, the default I/O page size
|
||||
is 16k, so mapping a simple mbuf wastes 31/32 of the address space.
|
||||
.Pp
|
||||
Another problem with most of these cards is that they support putting a 32-bit
|
||||
handle into the buffer descriptor together with the physical address.
|
||||
This handle is reflected back to the driver when the buffer is filled, and
|
||||
assists the driver in finding the buffer in host memory.
|
||||
For 32-bit machines,
|
||||
the virtual address of the buffer is usually used as the handle.
|
||||
This does not
|
||||
work for 64-bit machines for obvious reasons, so a mapping is needed between
|
||||
these handles and the buffers.
|
||||
This mapping should be possible without
|
||||
searching lists and the like.
|
||||
.Pp
|
||||
An mbuf pool overcomes both problems by allocating DMA-able memory page wise
|
||||
with a per-pool configurable page size.
|
||||
Each page is divided into a number of
|
||||
equally-sized chunks, the last
|
||||
.Dv MBPOOL_TRAILER_SIZE
|
||||
of which are used by the pool code (4 bytes).
|
||||
The rest of each chunk is
|
||||
usable as a buffer.
|
||||
There is a per-pool limit on pages that will be allocated.
|
||||
.Pp
|
||||
Additionally, the code manages two flags for each buffer:
|
||||
.Dq on-card
|
||||
and
|
||||
.Dq used .
|
||||
A buffer may be in one of three states:
|
||||
.Bl -tag -width "on-card"
|
||||
.It free
|
||||
None of the flags is set.
|
||||
.It on-card
|
||||
Both flags are set.
|
||||
The buffer is assumed to be handed over to the card and
|
||||
waiting to be filled.
|
||||
.It used
|
||||
The buffer was returned by the card and is now travelling through the system.
|
||||
.El
|
||||
.Pp
|
||||
A pool is created with
|
||||
.Fn mbp_create .
|
||||
This call specifies a DMA tag
|
||||
.Fa dmat
|
||||
to be used to create and map the memory pages via
|
||||
.Xr bus_dmamem_alloc 9 .
|
||||
The
|
||||
.Fa chunk_size
|
||||
includes the pool overhead.
|
||||
It means that to get buffers for 5 ATM cells
|
||||
(240 bytes), a chunk size of 256 should be specified.
|
||||
This results in 12 unused
|
||||
bytes between the buffer, and the pool overhead of four byte.
|
||||
The total
|
||||
maximum number of buffers in a pool is
|
||||
.Fa max_pages
|
||||
*
|
||||
.Fa ( page_size
|
||||
/
|
||||
.Fa chunk_size ) .
|
||||
The maximum value for
|
||||
.Fa max_pages
|
||||
is 2^14-1 (16383) and the maximum of
|
||||
.Fa page_size
|
||||
/
|
||||
.Fa chunk_size
|
||||
is 2^9 (512).
|
||||
If the call is successful, a pointer to a newly allocated
|
||||
.Vt "struct mbpool"
|
||||
is set into the variable pointed to by
|
||||
.Fa mpb .
|
||||
.Pp
|
||||
A pool is destroyed with
|
||||
.Fn mbp_destroy .
|
||||
This frees all pages and the pool structure itself.
|
||||
If compiled with
|
||||
.Dv DIAGNOSTICS ,
|
||||
the code checks that all buffers are free.
|
||||
If not, a warning message is issued
|
||||
to the console.
|
||||
.Pp
|
||||
A buffer is allocated with
|
||||
.Fn mbp_alloc .
|
||||
This returns the virtual address of the buffer and stores the physical
|
||||
address into the variable pointed to by
|
||||
.Fa pa .
|
||||
The handle is stored into the variable pointed to by
|
||||
.Fa hp .
|
||||
The two most significant bits and the 7 least significant bits of the handle
|
||||
are unused by the pool code and may be used by the caller.
|
||||
These are
|
||||
automatically stripped when passing a handle to one of the other functions.
|
||||
If a buffer cannot be allocated (either because the maximum number of pages
|
||||
is reached, no memory is available or the memory cannot be mapped),
|
||||
.Dv NULL
|
||||
is returned.
|
||||
If a buffer could be allocated, it is in the
|
||||
.Dq on-card
|
||||
state.
|
||||
.Pp
|
||||
When the buffer is returned by the card, the driver calls
|
||||
.Fn mbp_get
|
||||
with the handle.
|
||||
This function returns the virtual address of the buffer
|
||||
and clears the
|
||||
.Dq on-card
|
||||
bit.
|
||||
The buffer is now in the
|
||||
.Dq used
|
||||
state.
|
||||
The function
|
||||
.Fn mbp_get_keep
|
||||
differs from
|
||||
.Fn mbp_get
|
||||
in that it does not clear the
|
||||
.Dq on-card
|
||||
bit.
|
||||
This can be used for buffers
|
||||
that are returned
|
||||
.Dq partially
|
||||
by the card.
|
||||
.Pp
|
||||
A buffer is freed by calling
|
||||
.Fn mbp_free
|
||||
with the virtual address of the buffer.
|
||||
This clears the
|
||||
.Dq used
|
||||
bit, and
|
||||
puts the buffer on the free list of the pool.
|
||||
Note that free buffers
|
||||
are NOT returned to the system.
|
||||
The function
|
||||
.Fn mbp_ext_free
|
||||
can be given to
|
||||
.Fn m_extadd
|
||||
as the free function.
|
||||
.Pp
|
||||
Before using the contents of a buffer returned by the card, the driver
|
||||
must call
|
||||
.Fn mbp_sync
|
||||
with the appropriate parameters.
|
||||
This results in a call to
|
||||
.Xr bus_dmamap_sync 9
|
||||
for the buffer.
|
||||
.Pp
|
||||
All buffers in the pool that are currently in the
|
||||
.Dq on-card
|
||||
state can be freed
|
||||
with a call to
|
||||
.Fn mbp_card_free .
|
||||
This may be called by the driver when it stops the interface.
|
||||
Buffers in the
|
||||
.Dq used
|
||||
state are not freed by this call.
|
||||
.Pp
|
||||
For debugging it is possible to call
|
||||
.Fn mbp_count .
|
||||
This returns the number of buffers in the
|
||||
.Dq used
|
||||
and
|
||||
.Dq on-card
|
||||
states and
|
||||
the number of buffers on the free list.
|
||||
.Sh SEE ALSO
|
||||
.Xr mbuf 9
|
||||
.Sh AUTHORS
|
||||
.An Harti Brandt Aq Mt harti@FreeBSD.org
|
||||
.Sh CAVEATS
|
||||
The function
|
||||
.Fn mbp_sync
|
||||
is currently a no-op because
|
||||
.Xr bus_dmamap_sync 9
|
||||
is missing the offset and length parameters.
|
@ -2210,8 +2210,6 @@ device rtwnfw
|
||||
options MCLSHIFT=12 # mbuf cluster shift in bits, 12 == 4KB
|
||||
options MSIZE=512 # mbuf size in bytes
|
||||
|
||||
options LIBMBPOOL
|
||||
|
||||
#
|
||||
# Sound drivers
|
||||
#
|
||||
|
@ -3816,7 +3816,6 @@ kern/subr_kdb.c standard
|
||||
kern/subr_kobj.c standard
|
||||
kern/subr_lock.c standard
|
||||
kern/subr_log.c standard
|
||||
kern/subr_mbpool.c optional libmbpool
|
||||
kern/subr_mchain.c optional libmchain
|
||||
kern/subr_module.c standard
|
||||
kern/subr_msgbuf.c standard
|
||||
|
@ -432,7 +432,6 @@ IPSEC_SUPPORT opt_ipsec.h
|
||||
IPSTEALTH
|
||||
KRPC
|
||||
LIBALIAS
|
||||
LIBMBPOOL
|
||||
LIBMCHAIN
|
||||
MBUF_PROFILING
|
||||
MBUF_STRESS_TEST
|
||||
|
@ -1,398 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2003
|
||||
* Fraunhofer Institute for Open Communication Systems (FhG Fokus).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* Author: Hartmut Brandt <harti@freebsd.org>
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/module.h>
|
||||
|
||||
#include <machine/bus.h>
|
||||
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/mbpool.h>
|
||||
|
||||
MODULE_VERSION(libmbpool, 1);
|
||||
|
||||
/*
|
||||
* Memory is allocated as DMA-able pages. Each page is divided into a number
|
||||
* of equal chunks where the last 4 bytes of each chunk are occupied by
|
||||
* the page number and the chunk number. The caller must take these four
|
||||
* bytes into account when specifying the chunk size. Each page is mapped by
|
||||
* its own DMA map using the user specified DMA tag.
|
||||
*
|
||||
* Each chunk has a used and a card bit in the high bits of its page number.
|
||||
* 0 0 chunk is free and may be allocated
|
||||
* 1 1 chunk has been given to the interface
|
||||
* 0 1 chunk is traveling through the system
|
||||
* 1 0 illegal
|
||||
*/
|
||||
struct mbtrail {
|
||||
uint16_t chunk;
|
||||
uint16_t page;
|
||||
};
|
||||
#define MBP_CARD 0x8000
|
||||
#define MBP_USED 0x4000
|
||||
#define MBP_PMSK 0x3fff /* page number mask */
|
||||
#define MBP_CMSK 0x01ff /* chunk number mask */
|
||||
|
||||
struct mbfree {
|
||||
SLIST_ENTRY(mbfree) link; /* link on free list */
|
||||
};
|
||||
|
||||
struct mbpage {
|
||||
bus_dmamap_t map; /* map for this page */
|
||||
bus_addr_t phy; /* physical address */
|
||||
void *va; /* the memory */
|
||||
};
|
||||
|
||||
struct mbpool {
|
||||
const char *name; /* a name for this pool */
|
||||
bus_dma_tag_t dmat; /* tag for mapping */
|
||||
u_int max_pages; /* maximum number of pages */
|
||||
size_t page_size; /* size of each allocation */
|
||||
size_t chunk_size; /* size of each external mbuf */
|
||||
|
||||
struct mtx free_lock; /* lock of free list */
|
||||
SLIST_HEAD(, mbfree) free_list; /* free list */
|
||||
u_int npages; /* current number of pages */
|
||||
u_int nchunks; /* chunks per page */
|
||||
struct mbpage pages[]; /* pages */
|
||||
};
|
||||
|
||||
static MALLOC_DEFINE(M_MBPOOL, "mbpools", "mbuf pools");
|
||||
|
||||
/*
|
||||
* Make a trail pointer from a chunk pointer
|
||||
*/
|
||||
#define C2T(P, C) ((struct mbtrail *)((char *)(C) + (P)->chunk_size - \
|
||||
sizeof(struct mbtrail)))
|
||||
|
||||
/*
|
||||
* Make a free chunk pointer from a chunk number
|
||||
*/
|
||||
#define N2C(P, PG, C) ((struct mbfree *)((char *)(PG)->va + \
|
||||
(C) * (P)->chunk_size))
|
||||
|
||||
/*
|
||||
* Make/parse handles
|
||||
*/
|
||||
#define HMAKE(P, C) ((((P) & MBP_PMSK) << 16) | ((C) << 7))
|
||||
#define HPAGE(H) (((H) >> 16) & MBP_PMSK)
|
||||
#define HCHUNK(H) (((H) >> 7) & MBP_CMSK)
|
||||
|
||||
/*
|
||||
* initialize a pool
|
||||
*/
|
||||
int
|
||||
mbp_create(struct mbpool **pp, const char *name, bus_dma_tag_t dmat,
|
||||
u_int max_pages, size_t page_size, size_t chunk_size)
|
||||
{
|
||||
u_int nchunks;
|
||||
|
||||
if (max_pages > MBPOOL_MAX_MAXPAGES || chunk_size == 0)
|
||||
return (EINVAL);
|
||||
nchunks = page_size / chunk_size;
|
||||
if (nchunks == 0 || nchunks > MBPOOL_MAX_CHUNKS)
|
||||
return (EINVAL);
|
||||
|
||||
(*pp) = malloc(sizeof(struct mbpool) +
|
||||
max_pages * sizeof(struct mbpage),
|
||||
M_MBPOOL, M_WAITOK | M_ZERO);
|
||||
|
||||
(*pp)->name = name;
|
||||
(*pp)->dmat = dmat;
|
||||
(*pp)->max_pages = max_pages;
|
||||
(*pp)->page_size = page_size;
|
||||
(*pp)->chunk_size = chunk_size;
|
||||
(*pp)->nchunks = nchunks;
|
||||
|
||||
SLIST_INIT(&(*pp)->free_list);
|
||||
mtx_init(&(*pp)->free_lock, name, NULL, MTX_DEF);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* destroy a pool
|
||||
*/
|
||||
void
|
||||
mbp_destroy(struct mbpool *p)
|
||||
{
|
||||
u_int i;
|
||||
struct mbpage *pg;
|
||||
#ifdef DIAGNOSTIC
|
||||
struct mbtrail *tr;
|
||||
u_int b;
|
||||
#endif
|
||||
|
||||
for (i = 0; i < p->npages; i++) {
|
||||
pg = &p->pages[i];
|
||||
#ifdef DIAGNOSTIC
|
||||
for (b = 0; b < p->nchunks; b++) {
|
||||
tr = C2T(p, N2C(p, pg, b));
|
||||
if (tr->page & MBP_CARD)
|
||||
printf("%s: (%s) buf still on card"
|
||||
" %u/%u\n", __func__, p->name, i, b);
|
||||
if (tr->page & MBP_USED)
|
||||
printf("%s: (%s) sbuf still in use"
|
||||
" %u/%u\n", __func__, p->name, i, b);
|
||||
}
|
||||
#endif
|
||||
bus_dmamap_unload(p->dmat, pg->map);
|
||||
bus_dmamem_free(p->dmat, pg->va, pg->map);
|
||||
}
|
||||
mtx_destroy(&p->free_lock);
|
||||
|
||||
free(p, M_MBPOOL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Helper function when loading a one segment DMA buffer.
|
||||
*/
|
||||
static void
|
||||
mbp_callback(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
|
||||
{
|
||||
if (error == 0)
|
||||
*(bus_addr_t *)arg = segs[0].ds_addr;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a new page
|
||||
*/
|
||||
static void
|
||||
mbp_alloc_page(struct mbpool *p)
|
||||
{
|
||||
int error;
|
||||
struct mbpage *pg;
|
||||
u_int i;
|
||||
struct mbfree *f;
|
||||
struct mbtrail *t;
|
||||
|
||||
if (p->npages == p->max_pages) {
|
||||
#ifdef DIAGNOSTIC
|
||||
printf("%s: (%s) page limit reached %u\n", __func__,
|
||||
p->name, p->max_pages);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
pg = &p->pages[p->npages];
|
||||
|
||||
error = bus_dmamem_alloc(p->dmat, &pg->va, BUS_DMA_NOWAIT, &pg->map);
|
||||
if (error != 0)
|
||||
return;
|
||||
|
||||
error = bus_dmamap_load(p->dmat, pg->map, pg->va, p->page_size,
|
||||
mbp_callback, &pg->phy, 0);
|
||||
if (error != 0) {
|
||||
bus_dmamem_free(p->dmat, pg->va, pg->map);
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < p->nchunks; i++) {
|
||||
f = N2C(p, pg, i);
|
||||
t = C2T(p, f);
|
||||
t->page = p->npages;
|
||||
t->chunk = i;
|
||||
SLIST_INSERT_HEAD(&p->free_list, f, link);
|
||||
}
|
||||
|
||||
p->npages++;
|
||||
}
|
||||
|
||||
/*
|
||||
* allocate a chunk
|
||||
*/
|
||||
void *
|
||||
mbp_alloc(struct mbpool *p, bus_addr_t *pap, uint32_t *hp)
|
||||
{
|
||||
struct mbfree *cf;
|
||||
struct mbtrail *t;
|
||||
|
||||
mtx_lock(&p->free_lock);
|
||||
if ((cf = SLIST_FIRST(&p->free_list)) == NULL) {
|
||||
mbp_alloc_page(p);
|
||||
cf = SLIST_FIRST(&p->free_list);
|
||||
}
|
||||
if (cf == NULL) {
|
||||
mtx_unlock(&p->free_lock);
|
||||
return (NULL);
|
||||
}
|
||||
SLIST_REMOVE_HEAD(&p->free_list, link);
|
||||
mtx_unlock(&p->free_lock);
|
||||
|
||||
t = C2T(p, cf);
|
||||
|
||||
*pap = p->pages[t->page].phy + t->chunk * p->chunk_size;
|
||||
*hp = HMAKE(t->page, t->chunk);
|
||||
|
||||
t->page |= MBP_CARD | MBP_USED;
|
||||
|
||||
return (cf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Free a chunk
|
||||
*/
|
||||
void
|
||||
mbp_free(struct mbpool *p, void *ptr)
|
||||
{
|
||||
struct mbtrail *t;
|
||||
|
||||
mtx_lock(&p->free_lock);
|
||||
t = C2T(p, ptr);
|
||||
t->page &= ~(MBP_USED | MBP_CARD);
|
||||
SLIST_INSERT_HEAD(&p->free_list, (struct mbfree *)ptr, link);
|
||||
mtx_unlock(&p->free_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Mbuf system external mbuf free routine
|
||||
*/
|
||||
void
|
||||
mbp_ext_free(struct mbuf *m)
|
||||
{
|
||||
|
||||
mbp_free(m->m_ext.ext_arg2, m->m_ext.ext_arg1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Free all buffers that are marked as being on the card
|
||||
*/
|
||||
void
|
||||
mbp_card_free(struct mbpool *p)
|
||||
{
|
||||
u_int i, b;
|
||||
struct mbpage *pg;
|
||||
struct mbtrail *tr;
|
||||
struct mbfree *cf;
|
||||
|
||||
mtx_lock(&p->free_lock);
|
||||
for (i = 0; i < p->npages; i++) {
|
||||
pg = &p->pages[i];
|
||||
for (b = 0; b < p->nchunks; b++) {
|
||||
cf = N2C(p, pg, b);
|
||||
tr = C2T(p, cf);
|
||||
if (tr->page & MBP_CARD) {
|
||||
tr->page &= MBP_PMSK;
|
||||
SLIST_INSERT_HEAD(&p->free_list, cf, link);
|
||||
}
|
||||
}
|
||||
}
|
||||
mtx_unlock(&p->free_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Count buffers
|
||||
*/
|
||||
void
|
||||
mbp_count(struct mbpool *p, u_int *used, u_int *card, u_int *free)
|
||||
{
|
||||
u_int i, b;
|
||||
struct mbpage *pg;
|
||||
struct mbtrail *tr;
|
||||
struct mbfree *cf;
|
||||
|
||||
*used = *card = *free = 0;
|
||||
for (i = 0; i < p->npages; i++) {
|
||||
pg = &p->pages[i];
|
||||
for (b = 0; b < p->nchunks; b++) {
|
||||
tr = C2T(p, N2C(p, pg, b));
|
||||
if (tr->page & MBP_CARD)
|
||||
(*card)++;
|
||||
if (tr->page & MBP_USED)
|
||||
(*used)++;
|
||||
}
|
||||
}
|
||||
mtx_lock(&p->free_lock);
|
||||
SLIST_FOREACH(cf, &p->free_list, link)
|
||||
(*free)++;
|
||||
mtx_unlock(&p->free_lock);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the buffer from a handle and clear the card flag.
|
||||
*/
|
||||
void *
|
||||
mbp_get(struct mbpool *p, uint32_t h)
|
||||
{
|
||||
struct mbfree *cf;
|
||||
struct mbtrail *tr;
|
||||
|
||||
cf = N2C(p, &p->pages[HPAGE(h)], HCHUNK(h));
|
||||
tr = C2T(p, cf);
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
if (!(tr->page & MBP_CARD))
|
||||
printf("%s: (%s) chunk %u page %u not on card\n", __func__,
|
||||
p->name, HCHUNK(h), HPAGE(h));
|
||||
#endif
|
||||
|
||||
tr->page &= ~MBP_CARD;
|
||||
return (cf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the buffer from a handle and keep the card flag.
|
||||
*/
|
||||
void *
|
||||
mbp_get_keep(struct mbpool *p, uint32_t h)
|
||||
{
|
||||
struct mbfree *cf;
|
||||
struct mbtrail *tr;
|
||||
|
||||
cf = N2C(p, &p->pages[HPAGE(h)], HCHUNK(h));
|
||||
tr = C2T(p, cf);
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
if (!(tr->page & MBP_CARD))
|
||||
printf("%s: (%s) chunk %u page %u not on card\n", __func__,
|
||||
p->name, HCHUNK(h), HPAGE(h));
|
||||
#endif
|
||||
|
||||
return (cf);
|
||||
}
|
||||
|
||||
/*
|
||||
* sync the chunk
|
||||
*/
|
||||
void
|
||||
mbp_sync(struct mbpool *p, uint32_t h, bus_addr_t off, bus_size_t len, u_int op)
|
||||
{
|
||||
|
||||
#if 0
|
||||
bus_dmamap_sync_size(p->dmat, p->pages[HPAGE(h)].map,
|
||||
HCHUNK(h) * p->chunk_size + off, len, op);
|
||||
#endif
|
||||
}
|
@ -218,7 +218,6 @@ SUBDIR= \
|
||||
lge \
|
||||
libalias \
|
||||
libiconv \
|
||||
libmbpool \
|
||||
libmchain \
|
||||
${_linprocfs} \
|
||||
${_linsysfs} \
|
||||
|
@ -1,19 +0,0 @@
|
||||
# $FreeBSD$
|
||||
|
||||
.PATH: ${SRCTOP}/sys/kern
|
||||
|
||||
KMOD= libmbpool
|
||||
SRCS= subr_mbpool.c
|
||||
|
||||
EXPORT_SYMS= mbp_create \
|
||||
mbp_destroy \
|
||||
mbp_alloc \
|
||||
mbp_free \
|
||||
mbp_ext_free \
|
||||
mbp_card_free \
|
||||
mbp_count \
|
||||
mbp_get \
|
||||
mbp_get_keep \
|
||||
mbp_sync
|
||||
|
||||
.include <bsd.kmod.mk>
|
@ -1,90 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2003
|
||||
* Fraunhofer Institute for Open Communication Systems (FhG Fokus).
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* Author: Hartmut Brandt <harti@freebsd.org>
|
||||
*/
|
||||
|
||||
/*
|
||||
* This implements pools of DMA-able buffers that conserve DMA address space
|
||||
* by putting several buffers into one page and that allow to map between
|
||||
* 32-bit handles for the buffer and buffer addresses (to use 32-bit network
|
||||
* interfaces on 64bit machines). This assists network interfaces that may need
|
||||
* huge numbers of mbufs.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
#ifndef _SYS_MBPOOL_H_
|
||||
#define _SYS_MBPOOL_H_
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
#include <sys/queue.h>
|
||||
|
||||
/* opaque */
|
||||
struct mbpool;
|
||||
|
||||
/* size of reserved area at end of each chunk */
|
||||
#define MBPOOL_TRAILER_SIZE 4
|
||||
|
||||
/* maximum value of max_pages */
|
||||
#define MBPOOL_MAX_MAXPAGES ((1 << 14) - 1)
|
||||
|
||||
/* maximum number of chunks per page */
|
||||
#define MBPOOL_MAX_CHUNKS (1 << 9)
|
||||
|
||||
/* initialize a pool */
|
||||
int mbp_create(struct mbpool **, const char *, bus_dma_tag_t, u_int,
|
||||
size_t, size_t);
|
||||
|
||||
/* destroy a pool */
|
||||
void mbp_destroy(struct mbpool *);
|
||||
|
||||
/* allocate a chunk and set used and on card */
|
||||
void *mbp_alloc(struct mbpool *, bus_addr_t *, uint32_t *);
|
||||
|
||||
/* free a chunk */
|
||||
void mbp_free(struct mbpool *, void *);
|
||||
|
||||
/* free a chunk that is an external mbuf */
|
||||
void mbp_ext_free(struct mbuf *);
|
||||
|
||||
/* free all buffers that are marked to be on the card */
|
||||
void mbp_card_free(struct mbpool *);
|
||||
|
||||
/* count used buffers and buffers on card */
|
||||
void mbp_count(struct mbpool *, u_int *, u_int *, u_int *);
|
||||
|
||||
/* get the buffer from a handle and clear card bit */
|
||||
void *mbp_get(struct mbpool *, uint32_t);
|
||||
|
||||
/* get the buffer from a handle and don't clear card bit */
|
||||
void *mbp_get_keep(struct mbpool *, uint32_t);
|
||||
|
||||
/* sync the chunk */
|
||||
void mbp_sync(struct mbpool *, uint32_t, bus_addr_t, bus_size_t, u_int);
|
||||
|
||||
#endif /* _KERNEL */
|
||||
#endif /* _SYS_MBPOOL_H_ */
|
Loading…
Reference in New Issue
Block a user