feat: kprintf now goes into dedicated pseudo-dev rather than flooding the framebuffer
[lunaix-os.git] / lunaix-os / kernel / block / blkio.c
index bc0178c1be562c014fbee93b19979f94e7219c5c..9fcd670e350286b28a1a251eaf8503f7498650c6 100644 (file)
@@ -2,6 +2,8 @@
 #include <lunaix/mm/cake.h>
 #include <lunaix/mm/valloc.h>
 
+#include <sys/cpu.h>
+
 static struct cake_pile* blkio_reqpile;
 
 void
@@ -70,7 +72,7 @@ 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;
@@ -78,8 +80,25 @@ blkio_commit(struct blkio_context* ctx, struct blkio_req* req)
 
     // if the pipeline is not running (e.g., stalling). Then we should schedule
     // 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);
     }
 }
 
@@ -117,6 +136,4 @@ blkio_complete(struct blkio_req* req)
     }
 
     req->io_ctx->busy--;
-
-    blkio_schedule(req->io_ctx);
 }
\ No newline at end of file