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:
parent
185dc76169
commit
836e5d1360
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=14364
@ -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;
|
||||
|
@ -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_ */
|
||||
|
@ -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
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user