version 1.5, 2005/10/15 17:29:26 |
version 1.13, 2009/01/16 01:44:27 |
|
|
/* $NetBSD$ */ |
/* $NetBSD$ */ |
|
|
/*- |
/*- |
* Copyright (c)2004 YAMAMOTO Takashi, |
* Copyright (c)2004,2005,2006,2008,2009 YAMAMOTO Takashi, |
* All rights reserved. |
* All rights reserved. |
* |
* |
* Redistribution and use in source and binary forms, with or without |
* Redistribution and use in source and binary forms, with or without |
Line 47 struct cscan_queue { |
|
Line 47 struct cscan_queue { |
|
daddr_t cq_lastrawblkno; /* b_rawblkno of the last request */ |
daddr_t cq_lastrawblkno; /* b_rawblkno of the last request */ |
}; |
}; |
|
|
static int __inline cscan_empty(const struct cscan_queue *); |
static inline int cscan_empty(const struct cscan_queue *); |
static void cscan_put(struct cscan_queue *, struct buf *, int); |
static void cscan_put(struct cscan_queue *, struct buf *, int); |
static struct buf *cscan_get(struct cscan_queue *, int); |
static struct buf *cscan_get(struct cscan_queue *, int); |
static void cscan_init(struct cscan_queue *); |
static void cscan_init(struct cscan_queue *); |
|
|
static __inline int |
static inline int |
cscan_empty(const struct cscan_queue *q) |
cscan_empty(const struct cscan_queue *q) |
{ |
{ |
|
|
Line 159 struct bufq_priocscan { |
|
Line 159 struct bufq_priocscan { |
|
* how many requests to serve when having pending requests on other queues. |
* how many requests to serve when having pending requests on other queues. |
* |
* |
* XXX tune |
* XXX tune |
|
* be careful: while making these values larger likely |
|
* increases the total throughput, it can also increase latencies |
|
* for some workloads. |
*/ |
*/ |
const int priocscan_burst[] = { |
const int priocscan_burst[] = { |
64, 16, 4 |
64, 16, 4 |
Line 170 static struct buf *bufq_priocscan_get(st |
|
Line 173 static struct buf *bufq_priocscan_get(st |
|
|
|
BUFQ_DEFINE(priocscan, 40, bufq_priocscan_init); |
BUFQ_DEFINE(priocscan, 40, bufq_priocscan_init); |
|
|
static __inline struct cscan_queue *bufq_priocscan_selectqueue( |
static inline struct cscan_queue *bufq_priocscan_selectqueue( |
struct bufq_priocscan *, const struct buf *); |
struct bufq_priocscan *, const struct buf *); |
|
|
static __inline struct cscan_queue * |
static inline struct cscan_queue * |
bufq_priocscan_selectqueue(struct bufq_priocscan *q, const struct buf *bp) |
bufq_priocscan_selectqueue(struct bufq_priocscan *q, const struct buf *bp) |
{ |
{ |
static const int priocscan_priomap[] = { |
static const int priocscan_priomap[] = { |
Line 205 bufq_priocscan_get(struct bufq_state *bu |
|
Line 208 bufq_priocscan_get(struct bufq_state *bu |
|
const struct priocscan_queue *epq; |
const struct priocscan_queue *epq; |
const struct cscan_queue *cq; |
const struct cscan_queue *cq; |
struct buf *bp; |
struct buf *bp; |
boolean_t single; /* true if there's only one non-empty queue */ |
bool single; /* true if there's only one non-empty queue */ |
|
|
pq = &q->bq_queue[0]; |
pq = &q->bq_queue[0]; |
epq = pq + PRIOCSCAN_NQUEUE; |
epq = pq + PRIOCSCAN_NQUEUE; |
Line 220 bufq_priocscan_get(struct bufq_state *bu |
|
Line 223 bufq_priocscan_get(struct bufq_state *bu |
|
} |
} |
|
|
first = pq; |
first = pq; |
single = TRUE; |
single = true; |
for (npq = first + 1; npq < epq; npq++) { |
for (npq = first + 1; npq < epq; npq++) { |
cq = &npq->q_queue; |
cq = &npq->q_queue; |
if (!cscan_empty(cq)) { |
if (!cscan_empty(cq)) { |
single = FALSE; |
single = false; |
if (pq->q_burst > 0) |
if (pq->q_burst > 0) |
break; |
break; |
pq = npq; |
pq = npq; |
Line 280 bufq_priocscan_get(struct bufq_state *bu |
|
Line 283 bufq_priocscan_get(struct bufq_state *bu |
|
return bp; |
return bp; |
} |
} |
|
|
|
static struct buf * |
|
bufq_priocscan_cancel(struct bufq_state *bufq, struct buf *bp) |
|
{ |
|
struct bufq_priocscan * const q = bufq->bq_private; |
|
int i, j; |
|
|
|
for (i = 0; i < PRIOCSCAN_NQUEUE; i++) { |
|
struct cscan_queue * const cq = &q->bq_queue[i].q_queue; |
|
for (j = 0; j < 2; j++) { |
|
struct bqhead * const bqh = &cq->cq_head[j]; |
|
struct buf *bq; |
|
|
|
TAILQ_FOREACH(bq, bqh, b_actq) { |
|
if (bq == bp) { |
|
TAILQ_REMOVE(bqh, bp, b_actq); |
|
return bp; |
|
} |
|
} |
|
} |
|
} |
|
return NULL; |
|
} |
|
|
static void |
static void |
bufq_priocscan_init(struct bufq_state *bufq) |
bufq_priocscan_init(struct bufq_state *bufq) |
{ |
{ |
Line 288 bufq_priocscan_init(struct bufq_state *b |
|
Line 314 bufq_priocscan_init(struct bufq_state *b |
|
|
|
bufq->bq_get = bufq_priocscan_get; |
bufq->bq_get = bufq_priocscan_get; |
bufq->bq_put = bufq_priocscan_put; |
bufq->bq_put = bufq_priocscan_put; |
|
bufq->bq_cancel = bufq_priocscan_cancel; |
bufq->bq_private = malloc(sizeof(struct bufq_priocscan), |
bufq->bq_private = malloc(sizeof(struct bufq_priocscan), |
M_DEVBUF, M_ZERO); |
M_DEVBUF, M_ZERO); |
|
|