Changeset d5b37b6 in mainline for kernel/generic/src/console/console.c


Ignore:
Timestamp:
2025-04-17T15:14:03Z (5 days ago)
Author:
Jiří Zárevúcky <zarevucky.jiri@…>
Branches:
master
Children:
690ad20
Parents:
571cc2d
git-author:
Jiří Zárevúcky <zarevucky.jiri@…> (2025-04-11 17:35:09)
git-committer:
Jiří Zárevúcky <zarevucky.jiri@…> (2025-04-17 15:14:03)
Message:

Use a new syscall, SYS_KIO_READ, for reading from KIO buffer

Originally, the buffer memory was shared between kernel and
uspace, presumably to avoid the overhead of syscalls.
However, this makes synchronization with kernel impossible,
so it is not possible to ensure it works reliably without
random glitches. Also, relative to everything else /app/kio
does with the data, the syscall overhead is positively tiny.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/generic/src/console/console.c

    r571cc2d rd5b37b6  
    22 * Copyright (c) 2003 Josef Cejka
    33 * Copyright (c) 2005 Jakub Jermar
     4 * Copyright (c) 2025 Jiří Zárevúcky
    45 * All rights reserved.
    56 *
     
    3536
    3637#include <abi/kio.h>
    37 #include <arch.h>
    38 #include <assert.h>
    39 #include <atomic.h>
    4038#include <console/chardev.h>
    4139#include <console/console.h>
    42 #include <ddi/ddi.h>
    43 #include <ddi/irq.h>
    4440#include <errno.h>
    4541#include <ipc/event.h>
    46 #include <ipc/irq.h>
    47 #include <mm/frame.h> /* SIZE2FRAMES */
    4842#include <panic.h>
    4943#include <preemption.h>
    50 #include <proc/thread.h>
     44#include <proc/task.h>
    5145#include <putchar.h>
    5246#include <stdatomic.h>
    5347#include <stdio.h>
    5448#include <stdlib.h>  /* malloc */
    55 #include <str.h>
    5649#include <synch/mutex.h>
    5750#include <synch/spinlock.h>
    58 #include <synch/waitq.h>
    5951#include <syscall/copy.h>
    6052#include <sysinfo/sysinfo.h>
    61 #include <typedefs.h>
    6253
    6354#define KIO_PAGES    8
     
    6556
    6657/** Kernel log cyclic buffer */
    67 char32_t kio[KIO_LENGTH] __attribute__((aligned(PAGE_SIZE)));
     58static char32_t kio[KIO_LENGTH];
    6859
    6960/** Kernel log initialized */
     
    8778/** Kernel log spinlock */
    8879IRQ_SPINLOCK_INITIALIZE(kio_lock);
    89 
    90 /** Physical memory area used for kio buffer */
    91 static parea_t kio_parea;
    9280
    9381static indev_t stdin_sink;
     
    187175
    188176/** Initialize kernel logging facility
    189  *
    190  * The shared area contains kernel cyclic buffer. Userspace application may
    191  * be notified on new data with indication of position and size
    192  * of the data within the circular buffer.
    193  *
    194177 */
    195178void kio_init(void)
    196179{
    197         void *faddr = (void *) KA2PA(kio);
    198 
    199         assert((uintptr_t) faddr % FRAME_SIZE == 0);
    200 
    201         ddi_parea_init(&kio_parea);
    202         kio_parea.pbase = (uintptr_t) faddr;
    203         kio_parea.frames = SIZE2FRAMES(sizeof(kio));
    204         kio_parea.unpriv = false;
    205         kio_parea.mapped = false;
    206         ddi_parea_register(&kio_parea);
    207 
    208         sysinfo_set_item_val("kio.faddr", NULL, (sysarg_t) faddr);
    209         sysinfo_set_item_val("kio.pages", NULL, KIO_PAGES);
    210 
    211180        event_set_unmask_callback(EVENT_KIO, kio_update);
    212181        atomic_store(&kio_inited, true);
     
    332301        if (ch == '\n')
    333302                kio_update(NULL);
     303}
     304
     305/** Reads up to `size` characters from kio buffer starting at character `at`.
     306 *
     307 * @param size  Maximum number of characters that can be stored in buffer.
     308 *              Values greater than KIO_LENGTH are silently treated as KIO_LENGTH
     309 *              for the purposes of calculating the return value.
     310 * @return Number of characters read. Can be more than `size`.
     311 *         In that case, `size` characters are written to user buffer
     312 *         and the extra amount is the number of characters missed.
     313 */
     314sysarg_t sys_kio_read(uspace_addr_t buf, size_t size, size_t at)
     315{
     316        errno_t rc;
     317        size_t missed = 0;
     318
     319        irq_spinlock_lock(&kio_lock, true);
     320
     321        if (at == kio_written) {
     322                irq_spinlock_unlock(&kio_lock, true);
     323                return 0;
     324        }
     325
     326        size_t readable_chars = kio_written - at;
     327        if (readable_chars > KIO_LENGTH) {
     328                missed = readable_chars - KIO_LENGTH;
     329                readable_chars = KIO_LENGTH;
     330        }
     331
     332        size_t actual_read = min(readable_chars, size);
     333        size_t offset = (kio_written - readable_chars) % KIO_LENGTH;
     334
     335        if (offset + actual_read > KIO_LENGTH) {
     336                size_t first = KIO_LENGTH - offset;
     337                size_t last = actual_read - first;
     338                size_t first_bytes = first * sizeof(kio[0]);
     339                size_t last_bytes = last * sizeof(kio[0]);
     340
     341                rc = copy_to_uspace(buf, &kio[offset], first_bytes);
     342                if (rc == EOK)
     343                        rc = copy_to_uspace(buf + first_bytes, &kio[0], last_bytes);
     344        } else {
     345                rc = copy_to_uspace(buf, &kio[offset], actual_read * sizeof(kio[0]));
     346        }
     347
     348        irq_spinlock_unlock(&kio_lock, true);
     349
     350        if (rc != EOK) {
     351                log(LF_OTHER, LVL_WARN,
     352                    "[%s(%" PRIu64 ")] Terminating due to invalid memory buffer"
     353                    " in SYS_KIO_READ.\n", TASK->name, TASK->taskid);
     354                task_kill_self(true);
     355        }
     356
     357        return actual_read + missed;
    334358}
    335359
Note: See TracChangeset for help on using the changeset viewer.