- 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:
parent
ba540b27d6
commit
72142b2fae
@ -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"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user