X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/3b6a05fc894d0c1a3d431045ee5a53955ba093a0..707c6653985f55463e8a59a58b248ba8af3b44b2:/lunaix-os/kernel/block/blkio.c diff --git a/lunaix-os/kernel/block/blkio.c b/lunaix-os/kernel/block/blkio.c index 44531c4..0427622 100644 --- a/lunaix-os/kernel/block/blkio.c +++ b/lunaix-os/kernel/block/blkio.c @@ -2,6 +2,8 @@ #include #include +#include + static struct cake_pile* blkio_reqpile; void @@ -24,6 +26,7 @@ __blkio_req_create(struct vecbuf* buffer, .flags = options, .evt_args = evt_args }; breq->vbuf = buffer; + waitq_init(&breq->wait); return breq; } @@ -69,16 +72,33 @@ blkio_newctx(req_handler handler) } void -blkio_commit(struct blkio_context* ctx, struct blkio_req* req) +blkio_commit(struct blkio_context* ctx, struct blkio_req* req, int options) { req->flags |= BLKIO_PENDING; req->io_ctx = ctx; llist_append(&ctx->queue, &req->reqs); // if the pipeline is not running (e.g., stalling). Then we should schedule - // one immediately and kick it start. + // one immediately and kick it started. + // NOTE: Possible race condition between blkio_commit and pwait. + // Consider: what if scheduler complete the request before pwait even get + // called? + // Two possible work around: + // #1. we disable the interrupt before schedule the request. + // #2. we do scheduling within interrupt context (e.g., attach a timer) + // As we don't want to overwhelming the interrupt context and also keep the + // request RTT as small as possible, hence #1 is preferred. + if (!ctx->busy) { + if ((options & BLKIO_WAIT)) { + cpu_disable_interrupt(); + blkio_schedule(ctx); + pwait(&req->wait); + return; + } blkio_schedule(ctx); + } else if ((options & BLKIO_WAIT)) { + pwait(&req->wait); } } @@ -102,14 +122,18 @@ void blkio_complete(struct blkio_req* req) { req->flags &= ~(BLKIO_BUSY | BLKIO_PENDING); + if (req->completed) { req->completed(req); } + + // Wake all blocked processes on completion, + // albeit should be no more than one process in everycase (by design) + pwake_all(&req->wait); + if ((req->flags & BLKIO_FOC)) { blkio_free_req(req); } req->io_ctx->busy--; - - blkio_schedule(req->io_ctx); } \ No newline at end of file