1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-15 10:17:20 +00:00

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.
This commit is contained in:
John Dyson 1996-03-03 21:11:08 +00:00
parent 185dc76169
commit 836e5d1360
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=14364
5 changed files with 50 additions and 38 deletions

View File

@ -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 <sys/param.h>
@ -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 @@ rlist_free(rlp, start, end)
* "*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;

View File

@ -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_ */

View File

@ -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

View File

@ -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));

View File

@ -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 <sys/param.h>
@ -49,6 +49,7 @@
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/vm_extern.h>
#include <vm/swap_pager.h>
#include <miscfs/specfs/specdev.h>