--- zzzz-none-000/linux-4.9.276/kernel/printk/printk.c 2021-07-20 14:21:16.000000000 +0000 +++ falcon-5530-750/linux-4.9.276/kernel/printk/printk.c 2023-04-05 08:19:02.000000000 +0000 @@ -45,6 +45,10 @@ #include #include #include +#ifdef CONFIG_AVM_DEBUG +#include +#endif +#include #include #include @@ -128,13 +132,10 @@ /* * Set sysctl string accordingly: */ - if (devkmsg_log == DEVKMSG_LOG_MASK_ON) { - memset(devkmsg_log_str, 0, DEVKMSG_STR_MAX_SIZE); - strncpy(devkmsg_log_str, "on", 2); - } else if (devkmsg_log == DEVKMSG_LOG_MASK_OFF) { - memset(devkmsg_log_str, 0, DEVKMSG_STR_MAX_SIZE); - strncpy(devkmsg_log_str, "off", 3); - } + if (devkmsg_log == DEVKMSG_LOG_MASK_ON) + strcpy(devkmsg_log_str, "on"); + else if (devkmsg_log == DEVKMSG_LOG_MASK_OFF) + strcpy(devkmsg_log_str, "off"); /* else "ratelimit" which is set by default. */ /* @@ -213,16 +214,18 @@ static int __down_trylock_console_sem(unsigned long ip) { - if (down_trylock(&console_sem)) + if (yield_down_trylock(&console_sem)) return 1; - mutex_acquire(&console_lock_dep_map, 0, 1, ip); + if (yield_is_linux_context()) + mutex_acquire(&console_lock_dep_map, 0, 1, ip); return 0; } #define down_trylock_console_sem() __down_trylock_console_sem(_RET_IP_) #define up_console_sem() do { \ - mutex_release(&console_lock_dep_map, 1, _RET_IP_);\ - up(&console_sem);\ + if (yield_is_linux_context())\ + mutex_release(&console_lock_dep_map, 1, _RET_IP_);\ + yield_up(&console_sem);\ } while (0) /* @@ -323,11 +326,19 @@ * non-prinatable characters are escaped in the "\xff" notation. */ +#define TC_SET_YIELDCONTEXT(cpu, tc) ((cpu & 0xFF) | (tc << 8)) +#define TC_CPUCONTEXT(cpu_tcid) ((cpu_tcid) & 0xFF) +#define TC_YIELDCONTEXT(cpu_tcid) ((cpu_tcid) >> 8) + + enum log_flags { LOG_NOCONS = 1, /* already flushed, do not print to console */ LOG_NEWLINE = 2, /* text ended with a newline */ LOG_PREFIX = 4, /* text started with a prefix */ LOG_CONT = 8, /* text is a fragment of a continuation line */ +#if defined(CONFIG_AVM_DEBUG) + LOG_PRINTK_AVM = 0x10, +#endif /*--- #if defined(CONFIG_AVM_DEBUG) ---*/ }; struct printk_log { @@ -338,11 +349,18 @@ u8 facility; /* syslog facility */ u8 flags:5; /* internal record flags */ u8 level:3; /* syslog level */ +#if defined(CONFIG_AVM_DEBUG) && defined(CONFIG_SMP) + u8 cpu; + u8 yield_context; +#endif /*--- #if defined(CONFIG_AVM_DEBUG) && defined(CONFIG_SMP) ---*/ } #ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS __packed __aligned(4) #endif ; +#if defined(CONFIG_AVM_DEBUG) +static int force_printk_avm = 0; +#endif /*--- #if defined(CONFIG_AVM_DEBUG) ---*/ /* * The logbuf_lock protects kmsg buffer, indices, counters. This can be taken @@ -530,6 +548,9 @@ /* insert record into the buffer, discard old ones, update heads */ static int log_store(int facility, int level, +#if defined(CONFIG_AVM_DEBUG) && defined(CONFIG_SMP) + int cpu_tcid, +#endif enum log_flags flags, u64 ts_nsec, const char *dict, u16 dict_len, const char *text, u16 text_len) @@ -576,7 +597,11 @@ if (ts_nsec > 0) msg->ts_nsec = ts_nsec; else - msg->ts_nsec = local_clock(); + msg->ts_nsec = yield_local_clock(); +#if defined(CONFIG_AVM_DEBUG) && defined(CONFIG_SMP) + msg->cpu = TC_CPUCONTEXT(cpu_tcid); + msg->yield_context = TC_YIELDCONTEXT(cpu_tcid); +#endif /*--- #if defined(CONFIG_AVM_DEBUG) && defined(CONFIG_SMP) ---*/ memset(log_dict(msg) + dict_len, 0, pad_len); msg->len = size; @@ -1202,6 +1227,18 @@ } len += print_time(msg->ts_nsec, buf ? buf + len : NULL); +#if defined(CONFIG_AVM_DEBUG) && defined(CONFIG_SMP) + if ((msg->flags & LOG_PRINTK_AVM) && buf) { + if (len && buf[len - 1] == ' ') + len--; + if (msg->yield_context) { + len += sprintf(&buf[len], "[Y%x:%x]", msg->cpu, + msg->yield_context - 1 /* tc */); + } else { + len += sprintf(&buf[len], "[%x]", msg->cpu); + } + } +#endif /*--- #if defined(CONFIG_AVM_DEBUG) && defined(CONFIG_SMP) ---*/ return len; } @@ -1520,15 +1557,33 @@ * Call the console drivers, asking them to write out * log_buf[start] to log_buf[end - 1]. * The console_lock must be held. + * YIELD-Kontext-fest */ static void call_console_drivers(int level, +#if defined(CONFIG_AVM_DEBUG) && defined(CONFIG_PRINTK) + int flags, +#endif /*--- #if defined(CONFIG_AVM_DEBUG) && defined(CONFIG_PRINTK) ---*/ const char *ext_text, size_t ext_len, const char *text, size_t len) { struct console *con; - trace_console_rcuidle(text, len); - + if (yield_is_linux_context()) { + trace_console_rcuidle(text, len); + } +#if defined(CONFIG_AVM_IPI_YIELD) + else { + /*--- niemals Std-Konsole fuer yield-context! ---*/ + avm_debug_console_write(text, len); + return; + } +#endif /*--- #if defined(CONFIG_AVM_IPI_YIELD) ---*/ +#if defined(CONFIG_AVM_DEBUG) && defined(CONFIG_PRINTK) + if ((flags & LOG_PRINTK_AVM) && + (avm_debug_console_write(text, len) == 0)) { + return; + } +#endif /*--- #if defined(CONFIG_AVM_DEBUG) && defined(CONFIG_PRINTK) ---*/ if (!console_drivers) return; @@ -1601,6 +1656,9 @@ u8 facility; /* log facility of first message */ enum log_flags flags; /* prefix, newline flags */ bool flushed:1; /* buffer sealed and committed */ +#if defined(CONFIG_AVM_DEBUG) && defined(CONFIG_SMP) + int cpu_tcid; +#endif } cont; static void cont_flush(void) @@ -1615,7 +1673,11 @@ * console; wait for the console to pick up the rest of the * line. LOG_NOCONS suppresses a duplicated output. */ - log_store(cont.facility, cont.level, cont.flags | LOG_NOCONS, + log_store(cont.facility, cont.level, +#if defined(CONFIG_AVM_DEBUG) && defined(CONFIG_SMP) + cont.cpu_tcid, +#endif + cont.flags | LOG_NOCONS, cont.ts_nsec, NULL, 0, cont.buf, cont.len); cont.flushed = true; } else { @@ -1623,13 +1685,21 @@ * If no fragment of this line ever reached the console, * just submit it to the store and free the buffer. */ - log_store(cont.facility, cont.level, cont.flags, 0, + log_store(cont.facility, cont.level, +#if defined(CONFIG_AVM_DEBUG) && defined(CONFIG_SMP) + cont.cpu_tcid, +#endif + cont.flags, 0, NULL, 0, cont.buf, cont.len); cont.len = 0; } } -static bool cont_add(int facility, int level, enum log_flags flags, const char *text, size_t len) +static bool cont_add(int facility, int level, +#if defined(CONFIG_AVM_DEBUG) && defined(CONFIG_SMP) + int cpu_tcid, +#endif + enum log_flags flags, const char *text, size_t len) { if (cont.len && cont.flushed) return false; @@ -1648,10 +1718,13 @@ cont.facility = facility; cont.level = level; cont.owner = current; - cont.ts_nsec = local_clock(); + cont.ts_nsec = yield_local_clock(); cont.flags = flags; cont.cons = 0; cont.flushed = false; +#if defined(CONFIG_AVM_DEBUG) && defined(CONFIG_SMP) + cont.cpu_tcid = cpu_tcid; +#endif } memcpy(cont.buf + cont.len, text, len); @@ -1698,7 +1771,11 @@ return textlen; } -static size_t log_output(int facility, int level, enum log_flags lflags, const char *dict, size_t dictlen, char *text, size_t text_len) +static size_t log_output(int facility, int level, +#if defined(CONFIG_AVM_DEBUG) && defined(CONFIG_SMP) + int cpu_tcid, +#endif + enum log_flags lflags, const char *dict, size_t dictlen, char *text, size_t text_len) { /* * If an earlier line was buffered, and we're a continuation @@ -1706,7 +1783,11 @@ */ if (cont.len) { if (cont.owner == current && (lflags & LOG_CONT)) { - if (cont_add(facility, level, lflags, text, text_len)) + if (cont_add(facility, level, +#if defined(CONFIG_AVM_DEBUG) && defined(CONFIG_SMP) + cpu_tcid, +#endif + lflags, text, text_len)) return text_len; } /* Otherwise, make sure it's flushed */ @@ -1719,12 +1800,20 @@ /* If it doesn't end in a newline, try to buffer the current line */ if (!(lflags & LOG_NEWLINE)) { - if (cont_add(facility, level, lflags, text, text_len)) + if (cont_add(facility, level, +#if defined(CONFIG_AVM_DEBUG) && defined(CONFIG_SMP) + cpu_tcid, +#endif + lflags, text, text_len)) return text_len; } /* Store it in the record log */ - return log_store(facility, level, lflags, 0, dict, dictlen, text, text_len); + return log_store(facility, level, +#if defined(CONFIG_AVM_DEBUG) && defined(CONFIG_SMP) + cpu_tcid, +#endif + lflags, 0, dict, dictlen, text, text_len); } asmlinkage int vprintk_emit(int facility, int level, @@ -1736,7 +1825,7 @@ char *text = textbuf; size_t text_len = 0; enum log_flags lflags = 0; - unsigned long flags; + unsigned long flags = 0; int this_cpu; int printed_len = 0; int nmi_message_lost; @@ -1749,16 +1838,18 @@ in_sched = true; } - boot_delay_msec(level); - printk_delay(); + if (yield_is_linux_context()) { + boot_delay_msec(level); + printk_delay(); + } - local_irq_save(flags); - this_cpu = smp_processor_id(); + yield_local_irq_save(flags); + this_cpu = TC_SET_YIELDCONTEXT(smp_processor_id(), is_yield_context()); /* * Ouch, printk recursed into itself! */ - if (unlikely(logbuf_cpu == this_cpu)) { + if (unlikely(yield_is_linux_context() && logbuf_cpu == this_cpu)) { /* * If a crash is occurring during printk() on this CPU, * then try to get the crash message out but make sure @@ -1774,9 +1865,11 @@ zap_locks(); } - lockdep_off(); + if (yield_is_linux_context()) { + lockdep_off(); + } /* This stops the holder of console_sem just where we want him */ - raw_spin_lock(&logbuf_lock); + yield_raw_spin_lock(&logbuf_lock); logbuf_cpu = this_cpu; if (unlikely(recursion_bug)) { @@ -1785,7 +1878,11 @@ recursion_bug = false; /* emit KERN_CRIT message */ - printed_len += log_store(0, 2, LOG_PREFIX|LOG_NEWLINE, 0, + printed_len += log_store(0, 2, +#if defined(CONFIG_AVM_DEBUG) && defined(CONFIG_SMP) + this_cpu, +#endif + LOG_PREFIX|LOG_NEWLINE, 0, NULL, 0, recursion_msg, strlen(recursion_msg)); } @@ -1795,7 +1892,11 @@ text_len = scnprintf(textbuf, sizeof(textbuf), "BAD LUCK: lost %d message(s) from NMI context!", nmi_message_lost); - printed_len += log_store(0, 2, LOG_PREFIX|LOG_NEWLINE, 0, + printed_len += log_store(0, 2, +#if defined(CONFIG_AVM_DEBUG) && defined(CONFIG_SMP) + this_cpu, +#endif + LOG_PREFIX|LOG_NEWLINE, 0, NULL, 0, textbuf, text_len); } @@ -1810,6 +1911,14 @@ text_len--; lflags |= LOG_NEWLINE; } +#if defined(CONFIG_AVM_DEBUG) + if (facility & FORCE_PRINTK_LINUX_FACILITIES_VALUE) { + facility &= ~FORCE_PRINTK_LINUX_FACILITIES_VALUE; + } else if (force_printk_avm || (facility & FORCE_PRINTK_AVM_FACILITIES_VALUE)) { + facility &= ~FORCE_PRINTK_AVM_FACILITIES_VALUE; + lflags |= LOG_PRINTK_AVM; /*--- force console-output over avm_debug_console_write() ---*/ + } +#endif /* strip kernel syslog prefix and extract log level or control flags */ if (facility == 0) { @@ -1839,16 +1948,24 @@ if (dict) lflags |= LOG_PREFIX|LOG_NEWLINE; - printed_len += log_output(facility, level, lflags, dict, dictlen, text, text_len); + printed_len += log_output(facility, level, +#if defined(CONFIG_AVM_DEBUG) && defined(CONFIG_SMP) + this_cpu, +#endif + lflags, dict, dictlen, text, text_len); logbuf_cpu = UINT_MAX; - raw_spin_unlock(&logbuf_lock); - lockdep_on(); - local_irq_restore(flags); + yield_raw_spin_unlock(&logbuf_lock); + if (yield_is_linux_context()) { + lockdep_on(); + } + yield_local_irq_restore(flags); /* If called from the scheduler, we can not call up(). */ if (!in_sched) { - lockdep_off(); + if (yield_is_linux_context()) { + lockdep_off(); + } /* * Try to acquire and then immediately release the console * semaphore. The release will print out buffers and wake up @@ -1856,7 +1973,9 @@ */ if (console_trylock()) console_unlock(); - lockdep_on(); + if (yield_is_linux_context()) { + lockdep_on(); + } } return printed_len; @@ -1934,6 +2053,44 @@ } EXPORT_SYMBOL(printk); +#ifdef CONFIG_AVM_DEBUG +asmlinkage int printk_linux(const char *fmt, ...) +{ + va_list args; + int r; + + va_start(args, fmt); + r = vprintk_emit(FORCE_PRINTK_LINUX_FACILITIES_VALUE, -1, NULL, 0, fmt, + args); + va_end(args); + + return r; +} +EXPORT_SYMBOL(printk_linux); + +/*--------------------------------------------------------------------------------*\ + * ret: old-mode: 1 bended, 0: std.printk +\*--------------------------------------------------------------------------------*/ +int printk_avm_console_bend(unsigned int activate) +{ + int ret = 0; +#ifdef CONFIG_AVM_DEBUG + ret = force_printk_avm; + force_printk_avm = activate ? 1 : 0; +#endif /*--- #ifdef CONFIG_AVM_DEBUG ---*/ + return ret; +} +EXPORT_SYMBOL(printk_avm_console_bend); + +/*--------------------------------------------------------------------------------*\ +\*--------------------------------------------------------------------------------*/ +void vprintk_restore(void) +{ /* depreciated: use printk_avm_console_bend() instead */ + printk_avm_console_bend(0); +} +EXPORT_SYMBOL(vprintk_restore); +#endif /* CONFIG_AVM_ENHANCED */ + #else /* CONFIG_PRINTK */ #define LOG_LINE_MAX 0 @@ -1963,6 +2120,9 @@ char *dict, size_t dict_len, char *text, size_t text_len) { return 0; } static void call_console_drivers(int level, +#if defined(CONFIG_AVM_DEBUG) && defined(CONFIG_PRINTK) + int flags, +#endif /*--- #if defined(CONFIG_AVM_DEBUG) && defined(CONFIG_PRINTK) ---*/ const char *ext_text, size_t ext_len, const char *text, size_t len) {} static size_t msg_print_text(const struct printk_log *msg, @@ -1973,6 +2133,14 @@ /* Still needs to be defined for users */ DEFINE_PER_CPU(printk_func_t, printk_func); +#ifdef CONFIG_AVM_ENHANCED +static int no_vprintk(const char *fmt __maybe_unused, + va_list args __maybe_unused) +{ + return 0; +} +#endif /* CONFIG_AVM_ENHANCED */ + #endif /* CONFIG_PRINTK */ #ifdef CONFIG_EARLY_PRINTK @@ -2180,11 +2348,13 @@ * access to the console system and the console_drivers list. * * returns 1 on success, and 0 on failure to acquire the lock. + * YIELD-Kontext fest */ int console_trylock(void) { - if (down_trylock_console_sem()) + if (down_trylock_console_sem()) { return 0; + } if (console_suspended) { up_console_sem(); return 0; @@ -2201,7 +2371,7 @@ * rcu_preempt_depth(), otherwise RCU read sections modify * preempt_count(). */ - console_may_schedule = !oops_in_progress && + console_may_schedule = yield_is_linux_context() && !oops_in_progress && preemptible() && !rcu_preempt_depth(); return 1; @@ -2241,12 +2411,15 @@ return cpu_online(raw_smp_processor_id()) || have_callable_console(); } +/*--------------------------------------------------------------------------------*\ + * YIELD-Kontext fest +\*--------------------------------------------------------------------------------*/ static void console_cont_flush(char *text, size_t size) { unsigned long flags; size_t len; - raw_spin_lock_irqsave(&logbuf_lock, flags); + yield_raw_spin_lock_irqsave(&logbuf_lock, flags); if (!cont.len) goto out; @@ -2267,14 +2440,18 @@ goto out; len = cont_print_text(text, size); - raw_spin_unlock(&logbuf_lock); - stop_critical_timings(); - call_console_drivers(cont.level, NULL, 0, text, len); - start_critical_timings(); - local_irq_restore(flags); + yield_raw_spin_unlock(&logbuf_lock); + yield_stop_critical_timings(); + call_console_drivers(cont.level, +#if defined(CONFIG_AVM_DEBUG) && defined(CONFIG_PRINTK) + cont.flags, +#endif /*--- #if defined(CONFIG_AVM_DEBUG) && defined(CONFIG_PRINTK) ---*/ + NULL, 0, text, len); + yield_start_critical_timings(); + yield_local_irq_restore(flags); return; out: - raw_spin_unlock_irqrestore(&logbuf_lock, flags); + yield_raw_spin_unlock_irqrestore(&logbuf_lock, flags); } /** @@ -2290,6 +2467,7 @@ * If there is output waiting, we wake /dev/kmsg and syslog() users. * * console_unlock(); may be called from any context. + * YIELD-Kontext fest */ void console_unlock(void) { @@ -2343,7 +2521,7 @@ size_t len; int level; - raw_spin_lock_irqsave(&logbuf_lock, flags); + yield_raw_spin_lock_irqsave(&logbuf_lock, flags); if (seen_seq != log_next_seq) { wake_klogd = true; seen_seq = log_next_seq; @@ -2395,12 +2573,16 @@ } console_idx = log_next(console_idx); console_seq++; - raw_spin_unlock(&logbuf_lock); + yield_raw_spin_unlock(&logbuf_lock); - stop_critical_timings(); /* don't trace print latency */ - call_console_drivers(level, ext_text, ext_len, text, len); - start_critical_timings(); - local_irq_restore(flags); + yield_stop_critical_timings(); /* don't trace print latency */ + call_console_drivers(level, +#if defined(CONFIG_AVM_DEBUG) && defined(CONFIG_PRINTK) + msg->flags, +#endif /*--- #if defined(CONFIG_AVM_DEBUG) && defined(CONFIG_PRINTK) ---*/ + ext_text, ext_len, text, len); + yield_start_critical_timings(); + yield_local_irq_restore(flags); if (do_cond_resched) cond_resched(); @@ -2411,7 +2593,7 @@ if (unlikely(exclusive_console)) exclusive_console = NULL; - raw_spin_unlock(&logbuf_lock); + yield_raw_spin_unlock(&logbuf_lock); up_console_sem(); @@ -2421,14 +2603,14 @@ * there's a new owner and the console_unlock() from them will do the * flush, no worries. */ - raw_spin_lock(&logbuf_lock); + yield_raw_spin_lock(&logbuf_lock); retry = console_seq != log_next_seq; - raw_spin_unlock_irqrestore(&logbuf_lock, flags); + yield_raw_spin_unlock_irqrestore(&logbuf_lock, flags); if (retry && console_trylock()) goto again; - if (wake_klogd) + if (wake_klogd && yield_is_linux_context()) wake_up_klogd(); } EXPORT_SYMBOL(console_unlock); @@ -2900,6 +3082,27 @@ static DEFINE_SPINLOCK(dump_list_lock); static LIST_HEAD(dump_list); +#if defined(CONFIG_AVM_DEBUG) +bool kmsg_dump_get_buffer_nocontext(bool syslog, char *buf, size_t size, + size_t *len) +{ + struct kmsg_dumper _dumper, *dumper; + unsigned long flags; + + dumper = &_dumper; + /* initialize iterator with data about the stored records */ + dumper->active = true; + raw_spin_lock_irqsave(&logbuf_lock, flags); + dumper->cur_seq = clear_seq; + dumper->cur_idx = clear_idx; + dumper->next_seq = log_next_seq; + dumper->next_idx = log_next_idx; + raw_spin_unlock_irqrestore(&logbuf_lock, flags); + + return kmsg_dump_get_buffer(dumper, 0, buf, size, len); +} +#endif /*--- #if defined(CONFIG_AVM_DEBUG) ---*/ + /** * kmsg_dump_register - register a kernel log dumper. * @dumper: pointer to the kmsg_dumper structure