- Reduce contention on the global bdonelock and bpinlock by using

a pool mutex to protect these sleep/wakeup/counter races.  This
   still is preferable to bloating each bio with a mtx.
This commit is contained in:
jeff 2008-03-21 10:00:05 +00:00
parent ba540b27d6
commit 72142b2fae

View File

@ -236,17 +236,6 @@ static int needsbuffer;
*/ */
static struct mtx nblock; static struct mtx nblock;
/*
* Lock that protects against bwait()/bdone()/B_DONE races.
*/
static struct mtx bdonelock;
/*
* Lock that protects against bwait()/bdone()/B_DONE races.
*/
static struct mtx bpinlock;
/* /*
* Definitions for the buffer free lists. * Definitions for the buffer free lists.
*/ */
@ -540,8 +529,6 @@ bufinit(void)
mtx_init(&rbreqlock, "runningbufspace lock", NULL, MTX_DEF); mtx_init(&rbreqlock, "runningbufspace lock", NULL, MTX_DEF);
mtx_init(&nblock, "needsbuffer lock", NULL, MTX_DEF); mtx_init(&nblock, "needsbuffer lock", NULL, MTX_DEF);
mtx_init(&bdlock, "buffer daemon lock", NULL, MTX_DEF); mtx_init(&bdlock, "buffer daemon lock", NULL, MTX_DEF);
mtx_init(&bdonelock, "bdone lock", NULL, MTX_DEF);
mtx_init(&bpinlock, "bpin lock", NULL, MTX_DEF);
/* next, make a null set of free lists */ /* next, make a null set of free lists */
for (i = 0; i < BUFFER_QUEUES; i++) for (i = 0; i < BUFFER_QUEUES; i++)
@ -2994,14 +2981,16 @@ allocbuf(struct buf *bp, int size)
void void
biodone(struct bio *bp) biodone(struct bio *bp)
{ {
struct mtx *mtxp;
void (*done)(struct bio *); void (*done)(struct bio *);
mtx_lock(&bdonelock); mtxp = mtx_pool_find(mtxpool_sleep, bp);
mtx_lock(mtxp);
bp->bio_flags |= BIO_DONE; bp->bio_flags |= BIO_DONE;
done = bp->bio_done; done = bp->bio_done;
if (done == NULL) if (done == NULL)
wakeup(bp); wakeup(bp);
mtx_unlock(&bdonelock); mtx_unlock(mtxp);
if (done != NULL) if (done != NULL)
done(bp); done(bp);
} }
@ -3015,11 +3004,13 @@ biodone(struct bio *bp)
int int
biowait(struct bio *bp, const char *wchan) biowait(struct bio *bp, const char *wchan)
{ {
struct mtx *mtxp;
mtx_lock(&bdonelock); mtxp = mtx_pool_find(mtxpool_sleep, bp);
mtx_lock(mtxp);
while ((bp->bio_flags & BIO_DONE) == 0) while ((bp->bio_flags & BIO_DONE) == 0)
msleep(bp, &bdonelock, PRIBIO, wchan, hz / 10); msleep(bp, mtxp, PRIBIO, wchan, hz / 10);
mtx_unlock(&bdonelock); mtx_unlock(mtxp);
if (bp->bio_error != 0) if (bp->bio_error != 0)
return (bp->bio_error); return (bp->bio_error);
if (!(bp->bio_flags & BIO_ERROR)) if (!(bp->bio_flags & BIO_ERROR))
@ -3781,21 +3772,25 @@ vunmapbuf(struct buf *bp)
void void
bdone(struct buf *bp) bdone(struct buf *bp)
{ {
struct mtx *mtxp;
mtx_lock(&bdonelock); mtxp = mtx_pool_find(mtxpool_sleep, bp);
mtx_lock(mtxp);
bp->b_flags |= B_DONE; bp->b_flags |= B_DONE;
wakeup(bp); wakeup(bp);
mtx_unlock(&bdonelock); mtx_unlock(mtxp);
} }
void void
bwait(struct buf *bp, u_char pri, const char *wchan) bwait(struct buf *bp, u_char pri, const char *wchan)
{ {
struct mtx *mtxp;
mtx_lock(&bdonelock); mtxp = mtx_pool_find(mtxpool_sleep, bp);
mtx_lock(mtxp);
while ((bp->b_flags & B_DONE) == 0) while ((bp->b_flags & B_DONE) == 0)
msleep(bp, &bdonelock, pri, wchan, 0); msleep(bp, mtxp, pri, wchan, 0);
mtx_unlock(&bdonelock); mtx_unlock(mtxp);
} }
int int
@ -3873,27 +3868,36 @@ bufobj_wwait(struct bufobj *bo, int slpflag, int timeo)
void void
bpin(struct buf *bp) bpin(struct buf *bp)
{ {
mtx_lock(&bpinlock); struct mtx *mtxp;
mtxp = mtx_pool_find(mtxpool_sleep, bp);
mtx_lock(mtxp);
bp->b_pin_count++; bp->b_pin_count++;
mtx_unlock(&bpinlock); mtx_unlock(mtxp);
} }
void void
bunpin(struct buf *bp) bunpin(struct buf *bp)
{ {
mtx_lock(&bpinlock); struct mtx *mtxp;
mtxp = mtx_pool_find(mtxpool_sleep, bp);
mtx_lock(mtxp);
if (--bp->b_pin_count == 0) if (--bp->b_pin_count == 0)
wakeup(bp); wakeup(bp);
mtx_unlock(&bpinlock); mtx_unlock(mtxp);
} }
void void
bunpin_wait(struct buf *bp) bunpin_wait(struct buf *bp)
{ {
mtx_lock(&bpinlock); struct mtx *mtxp;
mtxp = mtx_pool_find(mtxpool_sleep, bp);
mtx_lock(mtxp);
while (bp->b_pin_count > 0) while (bp->b_pin_count > 0)
msleep(bp, &bpinlock, PRIBIO, "bwunpin", 0); msleep(bp, mtxp, PRIBIO, "bwunpin", 0);
mtx_unlock(&bpinlock); mtx_unlock(mtxp);
} }
#include "opt_ddb.h" #include "opt_ddb.h"