1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-02 08:42:48 +00:00

More aggressively rate limit the growth of soft dependency structures

in the face of multiple processes doing massive numbers of filesystem
operations. While this patch will work in nearly all situations, there
are still some perverse workloads that can overwhelm the system.
Detecting and handling these perverse workloads will be the subject
of another patch.

Reviewed by:	Paul Saab <ps@yahoo-inc.com>
Obtained from:	Ethan Solomita <ethan@geocast.com>
This commit is contained in:
Kirk McKusick 2000-11-20 06:22:39 +00:00
parent c71b3c67f1
commit 71868b020d
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=68933

View File

@ -440,6 +440,8 @@ static int softdep_worklist_busy;
static int max_softdeps; /* maximum number of structs before slowdown */
static int tickdelay = 2; /* number of ticks to pause during slowdown */
static int proc_waiting; /* tracks whether we have a timeout posted */
static int *stat_countp; /* statistic to count in proc_waiting timeout */
static struct callout_handle handle; /* handle on posted proc_waiting timeout */
static struct proc *filesys_syncer; /* proc of filesystem syncer process */
static int req_clear_inodedeps; /* syncer process flush some inodedeps */
#define FLUSH_INODES 1
@ -531,13 +533,13 @@ softdep_process_worklist(matchmnt)
*/
if (req_clear_inodedeps) {
clear_inodedeps(p);
req_clear_inodedeps = 0;
wakeup(&proc_waiting);
req_clear_inodedeps -= 1;
wakeup_one(&proc_waiting);
}
if (req_clear_remove) {
clear_remove(p);
req_clear_remove = 0;
wakeup(&proc_waiting);
req_clear_remove -= 1;
wakeup_one(&proc_waiting);
}
ACQUIRE_LOCK(&lk);
loopcount = 1;
@ -602,13 +604,13 @@ softdep_process_worklist(matchmnt)
*/
if (req_clear_inodedeps) {
clear_inodedeps(p);
req_clear_inodedeps = 0;
wakeup(&proc_waiting);
req_clear_inodedeps -= 1;
wakeup_one(&proc_waiting);
}
if (req_clear_remove) {
clear_remove(p);
req_clear_remove = 0;
wakeup(&proc_waiting);
req_clear_remove -= 1;
wakeup_one(&proc_waiting);
}
/*
* We do not generally want to stop for buffer space, but if
@ -1683,7 +1685,6 @@ softdep_setup_freeblocks(ip, length)
* been written to disk, so we can free any fragments without delay.
*/
merge_inode_lists(inodedep);
delay = (inodedep->id_state & DEPCOMPLETE);
while ((adp = TAILQ_FIRST(&inodedep->id_inoupdt)) != 0)
free_allocdirect(&inodedep->id_inoupdt, adp, delay);
FREE_LOCK(&lk);
@ -4347,7 +4348,6 @@ request_cleanup(resource, islocked)
int resource;
int islocked;
{
struct callout_handle handle;
struct proc *p = CURPROC;
/*
@ -4369,12 +4369,14 @@ request_cleanup(resource, islocked)
case FLUSH_INODES:
stat_ino_limit_push += 1;
req_clear_inodedeps = 1;
req_clear_inodedeps += 1;
stat_countp = &stat_ino_limit_hit;
break;
case FLUSH_REMOVE:
stat_blk_limit_push += 1;
req_clear_remove = 1;
req_clear_remove += 1;
stat_countp = &stat_blk_limit_hit;
break;
default:
@ -4386,29 +4388,14 @@ request_cleanup(resource, islocked)
*/
if (islocked == 0)
ACQUIRE_LOCK(&lk);
if (proc_waiting == 0) {
proc_waiting = 1;
handle = timeout(pause_timer, NULL,
tickdelay > 2 ? tickdelay : 2);
if (proc_waiting++ == 0) {
handle = timeout(pause_timer, 0, tickdelay > 2 ? tickdelay : 2);
}
FREE_LOCK_INTERLOCKED(&lk);
(void) tsleep((caddr_t)&proc_waiting, PPAUSE, "softupdate", 0);
ACQUIRE_LOCK_INTERLOCKED(&lk);
if (proc_waiting) {
untimeout(pause_timer, NULL, handle);
proc_waiting = 0;
} else {
switch (resource) {
case FLUSH_INODES:
stat_ino_limit_hit += 1;
break;
case FLUSH_REMOVE:
stat_blk_limit_hit += 1;
break;
}
}
if (--proc_waiting == 0)
untimeout(pause_timer, 0, handle);
if (islocked == 0)
FREE_LOCK(&lk);
return (1);
@ -4423,8 +4410,9 @@ pause_timer(arg)
void *arg;
{
proc_waiting = 0;
wakeup(&proc_waiting);
*stat_countp += 1;
handle = timeout(pause_timer, 0, tickdelay > 2 ? tickdelay : 2);
wakeup_one(&proc_waiting);
}
/*