Add the ability for pool caches to cache the physical address of

objects.  Clients of the pool_cache API must consistently use
the "paddr" variants or not, otherwise behavior is undefined.

Enable this on Alpha, ARM, MIPS, and x86.  Other platforms must
define POOL_VTOPHYS() in the appropriate manner in order to enable
the feature.

Part 1 of a series of simple patches contributed by Wasabi Systems
to improve network performance.
This commit is contained in:
thorpej 2003-04-09 18:22:13 +00:00
parent fe57487140
commit a0aee79a1d
7 changed files with 85 additions and 30 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: pmap.h,v 1.58 2003/01/17 22:11:16 thorpej Exp $ */
/* $NetBSD: pmap.h,v 1.59 2003/04/09 18:22:14 thorpej Exp $ */
/*-
* Copyright (c) 1998, 1999, 2000, 2001 The NetBSD Foundation, Inc.
@ -214,6 +214,11 @@ extern pt_entry_t *VPT; /* Virtual Page Table */
#define PMAP_MAP_POOLPAGE(pa) ALPHA_PHYS_TO_K0SEG((pa))
#define PMAP_UNMAP_POOLPAGE(va) ALPHA_K0SEG_TO_PHYS((va))
/*
* Other hooks for the pool allocator.
*/
#define POOL_VTOPHYS(va) ALPHA_K0SEG_TO_PHYS((va))
boolean_t pmap_pageidlezero(paddr_t);
#define PMAP_PAGEIDLEZERO(pa) pmap_pageidlezero((pa))

View File

@ -1,7 +1,7 @@
/* $NetBSD: pmap.h,v 1.63 2003/03/23 15:59:24 chris Exp $ */
/* $NetBSD: pmap.h,v 1.64 2003/04/09 18:22:14 thorpej Exp $ */
/*
* Copyright (c 2002 Wasabi Systems, Inc.
* Copyright (c) 2002 Wasabi Systems, Inc.
* All rights reserved.
*
* Written by Jason R. Thorpe for Wasabi Systems, Inc.
@ -440,6 +440,11 @@ extern void (*pmap_zero_page_func)(paddr_t);
#define L2_S_PROT(ku, pr) ((((ku) == PTE_USER) ? L2_S_PROT_U : 0) | \
(((pr) & VM_PROT_WRITE) ? L2_S_PROT_W : 0))
/*
* Hooks for the pool allocator.
*/
#define POOL_VTOPHYS(va) vtophys((vaddr_t) (va))
#endif /* _KERNEL */
#endif /* _ARM32_PMAP_H_ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: pmap.h,v 1.72 2003/04/09 18:17:34 thorpej Exp $ */
/* $NetBSD: pmap.h,v 1.73 2003/04/09 18:22:15 thorpej Exp $ */
/*
*
@ -504,5 +504,10 @@ void pmap_ldt_cleanup __P((struct lwp *));
#define PMAP_FORK
#endif /* USER_LDT */
/*
* Hooks for the pool allocator.
*/
#define POOL_VTOPHYS(va) vtophys((vaddr_t) (va))
#endif /* _KERNEL */
#endif /* _I386_PMAP_H_ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: pmap.h,v 1.41 2002/11/30 01:52:32 simonb Exp $ */
/* $NetBSD: pmap.h,v 1.42 2003/04/09 18:22:14 thorpej Exp $ */
/*
* Copyright (c) 1987 Carnegie-Mellon University
@ -151,6 +151,11 @@ void pmap_prefer(vaddr_t, vaddr_t *);
#define PMAP_MAP_POOLPAGE(pa) MIPS_PHYS_TO_KSEG0((pa))
#define PMAP_UNMAP_POOLPAGE(va) MIPS_KSEG0_TO_PHYS((va))
/*
* Other hooks for the pool allocator.
*/
#define POOL_VTOPHYS(va) MIPS_KSEG0_TO_PHYS((va))
/*
* Select CCA to use for unmanaged pages.
*/

View File

@ -1,4 +1,4 @@
/* $NetBSD: pmap.h,v 1.11 2003/04/02 07:53:59 thorpej Exp $ */
/* $NetBSD: pmap.h,v 1.12 2003/04/09 18:22:14 thorpej Exp $ */
/*
*
@ -588,5 +588,10 @@ void pmap_ldt_cleanup __P((struct lwp *));
#define PMAP_FORK
#endif /* USER_LDT */
/*
* Hooks for the pool allocator.
*/
#define POOL_VTOPHYS(va) vtophys((vaddr_t) (va))
#endif /* _KERNEL && !_LOCORE */
#endif /* _X86_64_PMAP_H_ */

View File

@ -1,4 +1,4 @@
/* $NetBSD: subr_pool.c,v 1.86 2003/03/16 08:06:51 matt Exp $ */
/* $NetBSD: subr_pool.c,v 1.87 2003/04/09 18:22:13 thorpej Exp $ */
/*-
* Copyright (c) 1997, 1999, 2000 The NetBSD Foundation, Inc.
@ -38,7 +38,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: subr_pool.c,v 1.86 2003/03/16 08:06:51 matt Exp $");
__KERNEL_RCSID(0, "$NetBSD: subr_pool.c,v 1.87 2003/04/09 18:22:13 thorpej Exp $");
#include "opt_pool.h"
#include "opt_poollog.h"
@ -1488,8 +1488,18 @@ pool_print1(struct pool *pp, const char *modif, void (*pr)(const char *, ...))
pc->pc_hits, pc->pc_misses, pc->pc_ngroups, pc->pc_nitems);
TAILQ_FOREACH(pcg, &pc->pc_grouplist, pcg_list) {
(*pr)("\t\tgroup %p: avail %d\n", pcg, pcg->pcg_avail);
for (i = 0; i < PCG_NOBJECTS; i++)
(*pr)("\t\t\t%p\n", pcg->pcg_objects[i]);
for (i = 0; i < PCG_NOBJECTS; i++) {
if (pcg->pcg_objects[i].pcgo_pa !=
POOL_PADDR_INVALID) {
(*pr)("\t\t\t%p, 0x%llx\n",
pcg->pcg_objects[i].pcgo_va,
(unsigned long long)
pcg->pcg_objects[i].pcgo_pa);
} else {
(*pr)("\t\t\t%p\n",
pcg->pcg_objects[i].pcgo_va);
}
}
}
}
@ -1618,7 +1628,7 @@ pool_cache_destroy(struct pool_cache *pc)
}
static __inline void *
pcg_get(struct pool_cache_group *pcg)
pcg_get(struct pool_cache_group *pcg, paddr_t *pap)
{
void *object;
u_int idx;
@ -1627,32 +1637,36 @@ pcg_get(struct pool_cache_group *pcg)
KASSERT(pcg->pcg_avail != 0);
idx = --pcg->pcg_avail;
KASSERT(pcg->pcg_objects[idx] != NULL);
object = pcg->pcg_objects[idx];
pcg->pcg_objects[idx] = NULL;
KASSERT(pcg->pcg_objects[idx].pcgo_va != NULL);
object = pcg->pcg_objects[idx].pcgo_va;
if (pap != NULL)
*pap = pcg->pcg_objects[idx].pcgo_pa;
pcg->pcg_objects[idx].pcgo_va = NULL;
return (object);
}
static __inline void
pcg_put(struct pool_cache_group *pcg, void *object)
pcg_put(struct pool_cache_group *pcg, void *object, paddr_t pa)
{
u_int idx;
KASSERT(pcg->pcg_avail < PCG_NOBJECTS);
idx = pcg->pcg_avail++;
KASSERT(pcg->pcg_objects[idx] == NULL);
pcg->pcg_objects[idx] = object;
KASSERT(pcg->pcg_objects[idx].pcgo_va == NULL);
pcg->pcg_objects[idx].pcgo_va = object;
pcg->pcg_objects[idx].pcgo_pa = pa;
}
/*
* pool_cache_get:
* pool_cache_get{,_paddr}:
*
* Get an object from a pool cache.
* Get an object from a pool cache (optionally returning
* the physical address of the object).
*/
void *
pool_cache_get(struct pool_cache *pc, int flags)
pool_cache_get_paddr(struct pool_cache *pc, int flags, paddr_t *pap)
{
struct pool_cache_group *pcg;
void *object;
@ -1687,13 +1701,20 @@ pool_cache_get(struct pool_cache *pc, int flags)
return (NULL);
}
}
if (object != NULL && pap != NULL) {
#ifdef POOL_VTOPHYS
*pap = POOL_VTOPHYS(object);
#else
*pap = POOL_PADDR_INVALID;
#endif
}
return (object);
}
have_group:
pc->pc_hits++;
pc->pc_nitems--;
object = pcg_get(pcg);
object = pcg_get(pcg, pap);
if (pcg->pcg_avail == 0)
pc->pc_allocfrom = NULL;
@ -1704,12 +1725,13 @@ pool_cache_get(struct pool_cache *pc, int flags)
}
/*
* pool_cache_put:
* pool_cache_put{,_paddr}:
*
* Put an object back to the pool cache.
* Put an object back to the pool cache (optionally caching the
* physical address of the object).
*/
void
pool_cache_put(struct pool_cache *pc, void *object)
pool_cache_put_paddr(struct pool_cache *pc, void *object, paddr_t pa)
{
struct pool_cache_group *pcg;
int s;
@ -1752,7 +1774,7 @@ pool_cache_put(struct pool_cache *pc, void *object)
have_group:
pc->pc_nitems++;
pcg_put(pcg, object);
pcg_put(pcg, object, pa);
if (pcg->pcg_avail == PCG_NOBJECTS)
pc->pc_freeto = NULL;
@ -1794,7 +1816,7 @@ pool_cache_do_invalidate(struct pool_cache *pc, int free_groups,
npcg = TAILQ_NEXT(pcg, pcg_list);
while (pcg->pcg_avail != 0) {
pc->pc_nitems--;
object = pcg_get(pcg);
object = pcg_get(pcg, NULL);
if (pcg->pcg_avail == 0 && pc->pc_allocfrom == pcg)
pc->pc_allocfrom = NULL;
if (pc->pc_dtor != NULL)

View File

@ -1,4 +1,4 @@
/* $NetBSD: pool.h,v 1.38 2002/08/25 23:03:39 thorpej Exp $ */
/* $NetBSD: pool.h,v 1.39 2003/04/09 18:22:13 thorpej Exp $ */
/*-
* Copyright (c) 1997, 1998, 1999, 2000 The NetBSD Foundation, Inc.
@ -57,6 +57,8 @@
#define PR_HASHTABSIZE 8
#define PCG_NOBJECTS 16
#define POOL_PADDR_INVALID ((paddr_t) -1)
#ifdef __POOL_EXPOSE
/* The pool cache group. */
struct pool_cache_group {
@ -64,7 +66,10 @@ struct pool_cache_group {
pcg_list; /* link in the pool cache's group list */
u_int pcg_avail; /* # available objects */
/* pointers to the objects */
void *pcg_objects[PCG_NOBJECTS];
struct {
void *pcgo_va; /* cache object virtual address */
paddr_t pcgo_pa;/* cache object physical address */
} pcg_objects[PCG_NOBJECTS];
};
struct pool_cache {
@ -250,8 +255,11 @@ void pool_cache_init(struct pool_cache *, struct pool *,
void (*dtor)(void *, void *),
void *);
void pool_cache_destroy(struct pool_cache *);
void *pool_cache_get(struct pool_cache *, int);
void pool_cache_put(struct pool_cache *, void *);
void *pool_cache_get_paddr(struct pool_cache *, int, paddr_t *);
#define pool_cache_get(pc, f) pool_cache_get_paddr((pc), (f), NULL)
void pool_cache_put_paddr(struct pool_cache *, void *, paddr_t);
#define pool_cache_put(pc, o) pool_cache_put_paddr((pc), (o), \
POOL_PADDR_INVALID)
void pool_cache_destruct_object(struct pool_cache *, void *);
void pool_cache_invalidate(struct pool_cache *);
#endif /* _KERNEL */