Move the stuff related to select and poll out of struct vnode.

The use of the zone allocator may or may not be overkill.
There is an XXX: over in ufs/ufs/ufs_vnops.c that jlemon may need
to revisit.

This shaves about 60 bytes of struct vnode which on my laptop means
600k less RAM used for vnodes.
This commit is contained in:
phk 2002-02-17 21:15:36 +00:00
parent 3348974369
commit c2a47cdbe8
3 changed files with 71 additions and 40 deletions

View File

@ -189,6 +189,7 @@ struct nfs_public nfs_pub;
/* Zone for allocation of new vnodes - used exclusively by getnewvnode() */ /* Zone for allocation of new vnodes - used exclusively by getnewvnode() */
static vm_zone_t vnode_zone; static vm_zone_t vnode_zone;
static vm_zone_t vnodepoll_zone;
/* Set to 1 to print out reclaim of active vnodes */ /* Set to 1 to print out reclaim of active vnodes */
int prtactive; int prtactive;
@ -253,6 +254,15 @@ static int vnlru_nowhere;
SYSCTL_INT(_debug, OID_AUTO, vnlru_nowhere, CTLFLAG_RW, &vnlru_nowhere, 0, SYSCTL_INT(_debug, OID_AUTO, vnlru_nowhere, CTLFLAG_RW, &vnlru_nowhere, 0,
"Number of times the vnlru process ran without success"); "Number of times the vnlru process ran without success");
static __inline void
v_addpollinfo(struct vnode *vp)
{
if (vp->v_pollinfo != NULL)
return;
vp->v_pollinfo = zalloc(vnodepoll_zone);
mtx_init(&vp->v_pollinfo->vpi_lock, "vnode pollinfo", MTX_DEF);
}
/* /*
* Initialize the vnode management data structures. * Initialize the vnode management data structures.
*/ */
@ -269,6 +279,7 @@ vntblinit(void *dummy __unused)
TAILQ_INIT(&vnode_free_list); TAILQ_INIT(&vnode_free_list);
mtx_init(&vnode_free_list_mtx, "vnode_free_list", MTX_DEF); mtx_init(&vnode_free_list_mtx, "vnode_free_list", MTX_DEF);
vnode_zone = zinit("VNODE", sizeof (struct vnode), 0, 0, 5); vnode_zone = zinit("VNODE", sizeof (struct vnode), 0, 0, 5);
vnodepoll_zone = zinit("VNODEPOLL", sizeof (struct vpollinfo), 0, 0, 5);
/* /*
* Initialize the filesystem syncer. * Initialize the filesystem syncer.
*/ */
@ -764,7 +775,6 @@ getnewvnode(tag, mp, vops, vpp)
freevnodes--; freevnodes--;
mtx_unlock(&vnode_free_list_mtx); mtx_unlock(&vnode_free_list_mtx);
cache_purge(vp); cache_purge(vp);
vp->v_lease = NULL;
if (vp->v_type != VBAD) { if (vp->v_type != VBAD) {
vgonel(vp, td); vgonel(vp, td);
} else { } else {
@ -786,6 +796,11 @@ getnewvnode(tag, mp, vops, vpp)
panic("Non-zero write count"); panic("Non-zero write count");
} }
#endif #endif
if (vp->v_pollinfo) {
mtx_destroy(&vp->v_pollinfo->vpi_lock);
zfree(vnodepoll_zone, vp->v_pollinfo);
}
vp->v_pollinfo = NULL;
vp->v_flag = 0; vp->v_flag = 0;
vp->v_lastw = 0; vp->v_lastw = 0;
vp->v_lasta = 0; vp->v_lasta = 0;
@ -798,7 +813,6 @@ getnewvnode(tag, mp, vops, vpp)
bzero((char *) vp, sizeof *vp); bzero((char *) vp, sizeof *vp);
mtx_init(&vp->v_interlock, "vnode interlock", MTX_DEF); mtx_init(&vp->v_interlock, "vnode interlock", MTX_DEF);
vp->v_dd = vp; vp->v_dd = vp;
mtx_init(&vp->v_pollinfo.vpi_lock, "vnode pollinfo", MTX_DEF);
cache_purge(vp); cache_purge(vp);
LIST_INIT(&vp->v_cache_src); LIST_INIT(&vp->v_cache_src);
TAILQ_INIT(&vp->v_cache_dst); TAILQ_INIT(&vp->v_cache_dst);
@ -2093,7 +2107,8 @@ vclean(vp, flags, td)
* Done with purge, notify sleepers of the grim news. * Done with purge, notify sleepers of the grim news.
*/ */
vp->v_op = dead_vnodeop_p; vp->v_op = dead_vnodeop_p;
vn_pollgone(vp); if (vp->v_pollinfo != NULL)
vn_pollgone(vp);
vp->v_tag = VT_NON; vp->v_tag = VT_NON;
vp->v_flag &= ~VXLOCK; vp->v_flag &= ~VXLOCK;
vp->v_vxproc = NULL; vp->v_vxproc = NULL;
@ -2709,8 +2724,10 @@ vn_pollrecord(vp, td, events)
struct thread *td; struct thread *td;
short events; short events;
{ {
mtx_lock(&vp->v_pollinfo.vpi_lock);
if (vp->v_pollinfo.vpi_revents & events) { v_addpollinfo(vp);
mtx_lock(&vp->v_pollinfo->vpi_lock);
if (vp->v_pollinfo->vpi_revents & events) {
/* /*
* This leaves events we are not interested * This leaves events we are not interested
* in available for the other process which * in available for the other process which
@ -2718,15 +2735,15 @@ vn_pollrecord(vp, td, events)
* (otherwise they would never have been * (otherwise they would never have been
* recorded). * recorded).
*/ */
events &= vp->v_pollinfo.vpi_revents; events &= vp->v_pollinfo->vpi_revents;
vp->v_pollinfo.vpi_revents &= ~events; vp->v_pollinfo->vpi_revents &= ~events;
mtx_unlock(&vp->v_pollinfo.vpi_lock); mtx_unlock(&vp->v_pollinfo->vpi_lock);
return events; return events;
} }
vp->v_pollinfo.vpi_events |= events; vp->v_pollinfo->vpi_events |= events;
selrecord(td, &vp->v_pollinfo.vpi_selinfo); selrecord(td, &vp->v_pollinfo->vpi_selinfo);
mtx_unlock(&vp->v_pollinfo.vpi_lock); mtx_unlock(&vp->v_pollinfo->vpi_lock);
return 0; return 0;
} }
@ -2741,8 +2758,10 @@ vn_pollevent(vp, events)
struct vnode *vp; struct vnode *vp;
short events; short events;
{ {
mtx_lock(&vp->v_pollinfo.vpi_lock);
if (vp->v_pollinfo.vpi_events & events) { v_addpollinfo(vp);
mtx_lock(&vp->v_pollinfo->vpi_lock);
if (vp->v_pollinfo->vpi_events & events) {
/* /*
* We clear vpi_events so that we don't * We clear vpi_events so that we don't
* call selwakeup() twice if two events are * call selwakeup() twice if two events are
@ -2754,15 +2773,15 @@ vn_pollevent(vp, events)
* a time. (Perhaps we should only clear those * a time. (Perhaps we should only clear those
* event bits which we note?) XXX * event bits which we note?) XXX
*/ */
vp->v_pollinfo.vpi_events = 0; /* &= ~events ??? */ vp->v_pollinfo->vpi_events = 0; /* &= ~events ??? */
vp->v_pollinfo.vpi_revents |= events; vp->v_pollinfo->vpi_revents |= events;
selwakeup(&vp->v_pollinfo.vpi_selinfo); selwakeup(&vp->v_pollinfo->vpi_selinfo);
} }
mtx_unlock(&vp->v_pollinfo.vpi_lock); mtx_unlock(&vp->v_pollinfo->vpi_lock);
} }
#define VN_KNOTE(vp, b) \ #define VN_KNOTE(vp, b) \
KNOTE((struct klist *)&vp->v_pollinfo.vpi_selinfo.si_note, (b)) KNOTE((struct klist *)&vp->v_pollinfo->vpi_selinfo.si_note, (b))
/* /*
* Wake up anyone polling on vp because it is being revoked. * Wake up anyone polling on vp because it is being revoked.
@ -2773,13 +2792,14 @@ void
vn_pollgone(vp) vn_pollgone(vp)
struct vnode *vp; struct vnode *vp;
{ {
mtx_lock(&vp->v_pollinfo.vpi_lock);
mtx_lock(&vp->v_pollinfo->vpi_lock);
VN_KNOTE(vp, NOTE_REVOKE); VN_KNOTE(vp, NOTE_REVOKE);
if (vp->v_pollinfo.vpi_events) { if (vp->v_pollinfo->vpi_events) {
vp->v_pollinfo.vpi_events = 0; vp->v_pollinfo->vpi_events = 0;
selwakeup(&vp->v_pollinfo.vpi_selinfo); selwakeup(&vp->v_pollinfo->vpi_selinfo);
} }
mtx_unlock(&vp->v_pollinfo.vpi_lock); mtx_unlock(&vp->v_pollinfo->vpi_lock);
} }

View File

@ -82,6 +82,13 @@ TAILQ_HEAD(buflists, buf);
typedef int vop_t __P((void *)); typedef int vop_t __P((void *));
struct namecache; struct namecache;
struct vpollinfo {
struct mtx vpi_lock; /* lock to protect below */
struct selinfo vpi_selinfo; /* identity of poller(s) */
short vpi_events; /* what they are looking for */
short vpi_revents; /* what has happened */
};
/* /*
* Reading or writing any of these items requires holding the appropriate lock. * Reading or writing any of these items requires holding the appropriate lock.
* v_freelist is locked by the global vnode_free_list mutex. * v_freelist is locked by the global vnode_free_list mutex.
@ -116,7 +123,7 @@ struct vnode {
} v_un; } v_un;
daddr_t v_lastw; /* last write (write cluster) */ daddr_t v_lastw; /* last write (write cluster) */
daddr_t v_cstart; /* start block of cluster */ daddr_t v_cstart; /* start block of cluster */
daddr_t v_lasta; /* last allocation */ daddr_t v_lasta; /* last allocation (cluster) */
int v_clen; /* length of current cluster */ int v_clen; /* length of current cluster */
struct vm_object *v_object; /* Place to store VM object */ struct vm_object *v_object; /* Place to store VM object */
struct mtx v_interlock; /* lock on usecount and flag */ struct mtx v_interlock; /* lock on usecount and flag */
@ -128,12 +135,7 @@ struct vnode {
TAILQ_HEAD(, namecache) v_cache_dst; /* Cache entries to us */ TAILQ_HEAD(, namecache) v_cache_dst; /* Cache entries to us */
struct vnode *v_dd; /* .. vnode */ struct vnode *v_dd; /* .. vnode */
u_long v_ddid; /* .. capability identifier */ u_long v_ddid; /* .. capability identifier */
struct { struct vpollinfo *v_pollinfo;
struct mtx vpi_lock; /* lock to protect below */
struct selinfo vpi_selinfo; /* identity of poller(s) */
short vpi_events; /* what they are looking for */
short vpi_revents; /* what has happened */
} v_pollinfo;
struct thread *v_vxproc; /* thread owning VXLOCK */ struct thread *v_vxproc; /* thread owning VXLOCK */
#ifdef DEBUG_LOCKS #ifdef DEBUG_LOCKS
const char *filename; /* Source file doing locking */ const char *filename; /* Source file doing locking */
@ -148,13 +150,16 @@ struct vnode {
#define VN_POLLEVENT(vp, events) \ #define VN_POLLEVENT(vp, events) \
do { \ do { \
if ((vp)->v_pollinfo.vpi_events & (events)) \ if ((vp)->v_pollinfo != NULL && \
(vp)->v_pollinfo->vpi_events & (events)) \
vn_pollevent((vp), (events)); \ vn_pollevent((vp), (events)); \
} while (0) } while (0)
#define VN_KNOTE(vp, b) \ #define VN_KNOTE(vp, b) \
KNOTE(&vp->v_pollinfo.vpi_selinfo.si_note, (b)) do { \
if ((vp)->v_pollinfo != NULL) \
KNOTE(&vp->v_pollinfo->vpi_selinfo.si_note, (b)); \
} while (0)
/* /*
* Vnode flags. * Vnode flags.

View File

@ -2473,9 +2473,14 @@ ufs_kqfilter(ap)
kn->kn_hook = (caddr_t)vp; kn->kn_hook = (caddr_t)vp;
mtx_lock(&vp->v_pollinfo.vpi_lock); if (vp->v_pollinfo == NULL) {
SLIST_INSERT_HEAD(&vp->v_pollinfo.vpi_selinfo.si_note, kn, kn_selnext); /* XXX: call v_addpollinfo(vp) ? */
mtx_unlock(&vp->v_pollinfo.vpi_lock); printf("ufs_kqfilter: vnode with no v_pollinfo\n");
return (1);
}
mtx_lock(&vp->v_pollinfo->vpi_lock);
SLIST_INSERT_HEAD(&vp->v_pollinfo->vpi_selinfo.si_note, kn, kn_selnext);
mtx_unlock(&vp->v_pollinfo->vpi_lock);
return (0); return (0);
} }
@ -2485,10 +2490,11 @@ filt_ufsdetach(struct knote *kn)
{ {
struct vnode *vp = (struct vnode *)kn->kn_hook; struct vnode *vp = (struct vnode *)kn->kn_hook;
mtx_lock(&vp->v_pollinfo.vpi_lock); KASSERT(vp->v_pollinfo != NULL, ("Mising v_pollinfo"));
SLIST_REMOVE(&vp->v_pollinfo.vpi_selinfo.si_note, mtx_lock(&vp->v_pollinfo->vpi_lock);
SLIST_REMOVE(&vp->v_pollinfo->vpi_selinfo.si_note,
kn, knote, kn_selnext); kn, knote, kn_selnext);
mtx_unlock(&vp->v_pollinfo.vpi_lock); mtx_unlock(&vp->v_pollinfo->vpi_lock);
} }
/*ARGSUSED*/ /*ARGSUSED*/