From 836e5d13605d7f4f84db462c8b447a4311f058b2 Mon Sep 17 00:00:00 2001 From: John Dyson Date: Sun, 3 Mar 1996 21:11:08 +0000 Subject: [PATCH] In order to fix some concurrency problems with the swap pager early on in the FreeBSD development, I had made a global lock around the rlist code. This was bogus, and now the lock is maintained on a per resource list basis. This now allows the rlist code to be used for almost any non-interrupt level application. --- sys/kern/subr_rlist.c | 60 ++++++++++++++++++++++--------------------- sys/sys/rlist.h | 18 +++++++++---- sys/vm/swap_pager.c | 4 +-- sys/vm/swap_pager.h | 3 ++- sys/vm/vm_swap.c | 3 ++- 5 files changed, 50 insertions(+), 38 deletions(-) diff --git a/sys/kern/subr_rlist.c b/sys/kern/subr_rlist.c index 19f0b8da0520..df4fc7d9fb54 100644 --- a/sys/kern/subr_rlist.c +++ b/sys/kern/subr_rlist.c @@ -54,7 +54,7 @@ * functioning of this software, nor does the author assume any responsibility * for damages incurred with its use. * - * $Id: subr_rlist.c,v 1.15 1995/12/14 08:31:45 phk Exp $ + * $Id: subr_rlist.c,v 1.16 1996/03/02 22:57:45 dyson Exp $ */ #include @@ -72,9 +72,8 @@ */ #define RLIST_MIN 128 -static int rlist_count=0, rlist_desired=0; +static int rlist_count=0; static struct rlist *rlfree; -static int rlist_active; static struct rlist *rlist_malloc __P((void)); @@ -115,19 +114,20 @@ rlist_mfree( struct rlist *rl) } void -rlist_free(rlp, start, end) - struct rlist **rlp; +rlist_free(rlh, start, end) + struct rlisthdr *rlh; u_int start, end; { + struct rlist **rlp = &rlh->rlh_list; struct rlist *prev_rlp = NULL, *cur_rlp = *rlp, *next_rlp = NULL; int s; s = splhigh(); - while (rlist_active) { - rlist_desired = 1; - tsleep((caddr_t)&rlist_active, PSWP, "rlistf", 0); + while (rlh->rlh_lock & RLH_LOCKED) { + rlh->rlh_lock |= RLH_DESIRED; + tsleep(rlh, PSWP, "rlistf", 0); } - rlist_active = 1; + rlh->rlh_lock |= RLH_LOCKED; splx(s); /* @@ -217,10 +217,10 @@ rlist_free(rlp, start, end) } done: - rlist_active = 0; - if (rlist_desired) { - wakeup((caddr_t)&rlist_active); - rlist_desired = 0; + rlh->rlh_lock &= ~RLH_LOCKED; + if (rlh->rlh_lock & RLH_DESIRED) { + wakeup(rlh); + rlh->rlh_lock &= ~RLH_DESIRED; } return; } @@ -232,20 +232,21 @@ done: * "*loc". (Note: loc can be zero if we don't wish the value) */ int -rlist_alloc (rlp, size, loc) - struct rlist **rlp; +rlist_alloc (rlh, size, loc) + struct rlisthdr *rlh; unsigned size, *loc; { + struct rlist **rlp = &rlh->rlh_list; register struct rlist *lp; int s; register struct rlist *olp = 0; s = splhigh(); - while( rlist_active) { - rlist_desired = 1; - tsleep((caddr_t)&rlist_active, PSWP, "rlista", 0); + while (rlh->rlh_lock & RLH_LOCKED) { + rlh->rlh_lock |= RLH_DESIRED; + tsleep(rlh, PSWP, "rlistf", 0); } - rlist_active = 1; + rlh->rlh_lock |= RLH_LOCKED; splx(s); /* walk list, allocating first thing that's big enough (first fit) */ @@ -271,20 +272,20 @@ rlist_alloc (rlp, size, loc) } } - rlist_active = 0; - if( rlist_desired) { - rlist_desired = 0; - wakeup((caddr_t)&rlist_active); + rlh->rlh_lock &= ~RLH_LOCKED; + if (rlh->rlh_lock & RLH_DESIRED) { + wakeup(rlh); + rlh->rlh_lock &= ~RLH_DESIRED; } return (1); } else { olp = *rlp; } - rlist_active = 0; - if( rlist_desired) { - rlist_desired = 0; - wakeup((caddr_t)&rlist_active); + rlh->rlh_lock &= ~RLH_LOCKED; + if (rlh->rlh_lock & RLH_DESIRED) { + wakeup(rlh); + rlh->rlh_lock &= ~RLH_DESIRED; } /* nothing in list that's big enough */ return (0); @@ -295,9 +296,10 @@ rlist_alloc (rlp, size, loc) * mark it as being empty. */ void -rlist_destroy (rlp) - struct rlist **rlp; +rlist_destroy (rlh) + struct rlisthdr *rlh; { + struct rlist **rlp = &rlh->rlh_list; struct rlist *lp, *nlp; lp = *rlp; diff --git a/sys/sys/rlist.h b/sys/sys/rlist.h index 5a02795de67b..cf86c8a84cb4 100644 --- a/sys/sys/rlist.h +++ b/sys/sys/rlist.h @@ -16,7 +16,7 @@ * rlist_alloc(&swapmap, 100, &loc); obtain 100 sectors from swap * * from: unknown? - * $Id: rlist.h,v 1.7 1994/10/09 07:35:10 davidg Exp $ + * $Id: rlist.h,v 1.8 1996/01/30 23:01:12 mpp Exp $ */ #ifndef _SYS_RLIST_H_ @@ -29,11 +29,19 @@ struct rlist { struct rlist *rl_next; /* next list entry, if present */ }; -extern struct rlist *swaplist; +struct rlisthdr { + int rlh_lock; /* list lock */ + struct rlist *rlh_list; /* list itself */ +}; + +#define RLH_DESIRED 0x2 +#define RLH_LOCKED 0x1 + +/* extern struct rlisthdr swaplist; */ /* Functions to manipulate resource lists. */ -extern void rlist_free __P((struct rlist **, unsigned, unsigned)); -int rlist_alloc __P((struct rlist **, unsigned, unsigned *)); -extern void rlist_destroy __P((struct rlist **)); +extern void rlist_free __P((struct rlisthdr *, unsigned, unsigned)); +int rlist_alloc __P((struct rlisthdr *, unsigned, unsigned *)); +extern void rlist_destroy __P((struct rlisthdr *)); #endif /* _SYS_RLIST_H_ */ diff --git a/sys/vm/swap_pager.c b/sys/vm/swap_pager.c index ea062fc3f77e..eb42e471a88b 100644 --- a/sys/vm/swap_pager.c +++ b/sys/vm/swap_pager.c @@ -39,7 +39,7 @@ * from: Utah $Hdr: swap_pager.c 1.4 91/04/30$ * * @(#)swap_pager.c 8.9 (Berkeley) 3/21/94 - * $Id: swap_pager.c,v 1.60 1996/01/31 13:14:21 davidg Exp $ + * $Id: swap_pager.c,v 1.61 1996/03/02 02:54:17 dyson Exp $ */ /* @@ -80,7 +80,7 @@ static int nswiodone; int swap_pager_full; extern int vm_swap_size; static int no_swap_space = 1; -struct rlist *swaplist; +struct rlisthdr swaplist; #define MAX_PAGEOUT_CLUSTER 16 diff --git a/sys/vm/swap_pager.h b/sys/vm/swap_pager.h index 231e0bbcbe69..3fdd44e7a6d0 100644 --- a/sys/vm/swap_pager.h +++ b/sys/vm/swap_pager.h @@ -36,7 +36,7 @@ * SUCH DAMAGE. * * from: @(#)swap_pager.h 7.1 (Berkeley) 12/5/90 - * $Id: swap_pager.h,v 1.13 1995/12/14 09:54:54 phk Exp $ + * $Id: swap_pager.h,v 1.14 1996/01/30 23:02:29 mpp Exp $ */ /* @@ -66,6 +66,7 @@ typedef struct swblock *sw_blk_t; #ifdef KERNEL extern struct pagerlst swap_pager_un_object_list; extern int swap_pager_full; +extern struct rlisthdr swaplist; int swap_pager_putpages __P((vm_object_t, vm_page_t *, int, boolean_t, int *)); int swap_pager_swp_alloc __P((vm_object_t, int)); diff --git a/sys/vm/vm_swap.c b/sys/vm/vm_swap.c index 8720286eb892..eac78ca2d6e7 100644 --- a/sys/vm/vm_swap.c +++ b/sys/vm/vm_swap.c @@ -31,7 +31,7 @@ * SUCH DAMAGE. * * @(#)vm_swap.c 8.5 (Berkeley) 2/17/94 - * $Id: vm_swap.c,v 1.33 1995/12/14 09:55:12 phk Exp $ + * $Id: vm_swap.c,v 1.34 1995/12/21 20:09:46 julian Exp $ */ #include @@ -49,6 +49,7 @@ #include #include #include +#include #include