|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Minios-devel] [UNIKRAFT PATCH] plat/xen: Do not discard characters on console
Retry sending characters to console ring instead of discarding
them whenever the ring is full (busy wait).
Signed-off-by: Simon Kuenzer <simon.kuenzer@xxxxxxxxx>
---
plat/xen/console.c | 35 +++++++++++++++++++++++++++++++----
1 file changed, 31 insertions(+), 4 deletions(-)
diff --git a/plat/xen/console.c b/plat/xen/console.c
index f2f0e78..2a776ee 100644
--- a/plat/xen/console.c
+++ b/plat/xen/console.c
@@ -132,6 +132,21 @@ static int emergency_output(const char *str, unsigned int
len)
}
#endif
+/*
+ * hvconsole_output can operate in two modes: buffered and intialized.
+ * The buffered mode is automatically activated after
+ * _libxenplat_prepare_console() was called and we know where the console ring
+ * is. The output string is put to the console ring until the ring is full. Any
+ * further characters are discarded. Since the event channel is not initialized
+ * yet, the backend is not notified. This mode is introduced to support early
+ * printing, even before events are not intialized.
+ * _libxenplat_init_console() finalizes the initialization and enables
+ * the event channel. From now on, the console backend is notified whenever
+ * we put characters on the console ring. Whenever this ring is full and there
+ * are still characters that should be printed, we are entering a busy loop and
+ * wait for the backend to make us space again. Of course this is slow: do not
+ * print so much! ;-)
+ */
static int hvconsole_output(const char *str, unsigned int len)
{
unsigned int sent = 0;
@@ -140,6 +155,7 @@ static int hvconsole_output(const char *str, unsigned int
len)
if (unlikely(!console_ring))
return sent;
+retry:
cons = console_ring->out_cons;
prod = console_ring->out_prod;
@@ -148,12 +164,13 @@ static int hvconsole_output(const char *str, unsigned int
len)
while ((sent < len) && ((prod - cons) < sizeof(console_ring->out))) {
if (str[sent] == '\n') {
- /* Convert: '\n' -> '\r''\n' */
+ /* prepend '\r' for converting '\n' to '\r''\n' */
+ if ((prod + 1 - cons) >= sizeof(console_ring->out))
+ break; /* not enough space for '\r' and '\n'! */
+
console_ring->out[MASK_XENCONS_IDX(prod++,
console_ring->out)] =
'\r';
- if ((prod - cons) >= sizeof(console_ring->out))
- break; /* no more space left */
}
console_ring->out[MASK_XENCONS_IDX(prod++, console_ring->out)] =
@@ -163,8 +180,18 @@ static int hvconsole_output(const char *str, unsigned int
len)
wmb(); /* ensure characters are written before increasing out_prod */
console_ring->out_prod = prod;
- if (likely(console_ready && console_evtchn))
+ /* Is the console fully initialized?
+ * Are we able to notify the backend?
+ */
+ if (likely(console_ready && console_evtchn)) {
notify_remote_via_evtchn(console_evtchn);
+
+ /* There are still bytes left to send out? If yes, do not
+ * discard them, retry sending (enters busy waiting)
+ */
+ if (sent < len)
+ goto retry;
+ }
return sent;
}
--
2.7.4
_______________________________________________
Minios-devel mailing list
Minios-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/minios-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |