--- zzzz-none-000/linux-3.10.107/kernel/printk.c 2017-06-27 09:49:32.000000000 +0000 +++ vr9-7490-729/linux-3.10.107/kernel/printk.c 2021-11-10 11:53:56.000000000 +0000 @@ -45,9 +45,19 @@ #include #include #include +#ifdef CONFIG_AVM_DEBUG +#include +#if defined(CONFIG_SMP) && defined(CONFIG_MIPS) +#include +#endif/*--- #if defined(CONFIG_SMP) && defined(CONFIG_MIPS) ---*/ +#endif/*--- #ifdef CONFIG_AVM_DEBUG ---*/ #include +#define yield_start_critical_timings() if(yield_is_linux_context()) start_critical_timings() +#define yield_stop_critical_timings() if(yield_is_linux_context()) stop_critical_timings() +#define yield_local_clock() (yield_is_linux_context() ? local_clock() : (u64)(jiffies - INITIAL_JIFFIES) * (NSEC_PER_SEC / HZ)) + #define CREATE_TRACE_POINTS #include @@ -198,6 +208,9 @@ 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 log { @@ -208,7 +221,14 @@ 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) ---*/ }; +#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. It is also @@ -242,7 +262,7 @@ static u32 clear_idx; #define PREFIX_MAX 32 -#define LOG_LINE_MAX 1024 - PREFIX_MAX +#define LOG_LINE_MAX (1024 - PREFIX_MAX) /* record buffer */ #if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) @@ -354,7 +374,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 = logbuf_cpu & 0xFF; + msg->yield_context = is_yield_context(); +#endif/*--- #if defined(CONFIG_AVM_DEBUG) && defined(CONFIG_SMP) ---*/ memset(log_dict(msg) + dict_len, 0, pad_len); msg->len = sizeof(struct log) + text_len + dict_len + pad_len; @@ -712,7 +736,7 @@ /* * This appends the listed symbols to /proc/vmcoreinfo * - * /proc/vmcoreinfo is used by various utiilties, like crash and makedumpfile to + * /proc/vmcoreinfo is used by various utilties, like crash and makedumpfile to * obtain access to symbols that are otherwise very difficult to locate. These * symbols are specifically used so that utilities can access and extract the * dmesg log from a vmcore file after a crash. @@ -880,7 +904,7 @@ if (!buf) return snprintf(NULL, 0, "[%5lu.000000] ", (unsigned long)ts); - return sprintf(buf, "[%5lu.%06lu] ", + return sprintf(buf, "[%5lu.%06lu] ", (unsigned long)ts, rem_nsec / 1000); } @@ -902,8 +926,17 @@ len++; } } - 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; } @@ -1265,15 +1298,32 @@ * 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, const char *text, size_t len) -{ +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 *text, size_t len) { struct console *con; - trace_console_rcuidle(text, len); - + if(yield_is_linux_context()) { + trace_console_rcuidle(text, len); + } if (level >= console_loglevel && !ignore_loglevel) return; +#if defined(CONFIG_AVM_IPI_YIELD) + if(!yield_is_linux_context()) { + /*--- 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; @@ -1347,6 +1397,7 @@ * This gets called with the 'logbuf_lock' spinlock held and * interrupts disabled. It should return with 'lockbuf_lock' * released but interrupts still disabled. + * YIELD-Kontext fest */ static int console_trylock_for_printk(unsigned int cpu) __releases(&logbuf_lock) @@ -1369,9 +1420,9 @@ } } logbuf_cpu = UINT_MAX; - raw_spin_unlock(&logbuf_lock); + yield_raw_spin_unlock(&logbuf_lock); if (wake) - up(&console_sem); + yield_up(&console_sem); return retval; } @@ -1435,14 +1486,22 @@ } } -static bool cont_add(int facility, int level, const char *text, size_t len) +static bool cont_add( +#if defined(CONFIG_AVM_DEBUG) + int lflag_force_avm_printk, +#endif/*--- #if defined(CONFIG_AVM_DEBUG) ---*/ + int facility, int level, const char *text, size_t len) { if (cont.len && cont.flushed) return false; if (cont.len + len > sizeof(cont.buf)) { /* the line gets too long, split it up in separate records */ - cont_flush(LOG_CONT); + cont_flush(LOG_CONT +#if defined(CONFIG_AVM_DEBUG) + | lflag_force_avm_printk +#endif/*--- #if defined(CONFIG_AVM_DEBUG) ---*/ + ); return false; } @@ -1450,8 +1509,12 @@ cont.facility = facility; cont.level = level; cont.owner = current; - cont.ts_nsec = local_clock(); - cont.flags = 0; + cont.ts_nsec = yield_local_clock(); + cont.flags = 0 +#if defined(CONFIG_AVM_DEBUG) + | lflag_force_avm_printk +#endif/*--- #if defined(CONFIG_AVM_DEBUG) ---*/ + ; cont.cons = 0; cont.flushed = false; } @@ -1459,8 +1522,13 @@ memcpy(cont.buf + cont.len, text, len); cont.len += len; - if (cont.len > (sizeof(cont.buf) * 80) / 100) - cont_flush(LOG_CONT); + if (cont.len > (sizeof(cont.buf) * 80) / 100) { + cont_flush(LOG_CONT +#if defined(CONFIG_AVM_DEBUG) + | lflag_force_avm_printk +#endif/*--- #if defined(CONFIG_AVM_DEBUG) ---*/ + ); + } return true; } @@ -1492,6 +1560,35 @@ } return textlen; } +#if !defined(CONFIG_AVM_IPI_YIELD) +/*--------------------------------------------------------------------------------*\ + output from yield (nonlinux!) goes never over the standard-console! +\*--------------------------------------------------------------------------------*/ +static int print_yield_output(int level, int this_cpu, char *text, int len, enum log_flags lflags) { + char txt[64]; + int txt_len = 0; + u64 ts_nsec; + + if (level >= console_loglevel && !ignore_loglevel) { + return 0; + } + + if(lflags & LOG_PREFIX) { + ts_nsec = (u64)(jiffies - INITIAL_JIFFIES) * (NSEC_PER_SEC / HZ); + txt_len = print_time(ts_nsec, txt); + if(txt_len) { + txt_len--; + } + txt_len += sprintf(&txt[txt_len], "[Y%d:%d]", this_cpu & 0xFF, (this_cpu >> 8) & 0xFF /* tc */); + avm_debug_console_write(txt, txt_len); + } + avm_debug_console_write(text, len); + if(lflags & LOG_NEWLINE) { + avm_debug_console_write("\n", 1); + } + return len + txt_len; +} +#endif/*--- #if !defined(CONFIG_AVM_IPI_YIELD) ---*/ asmlinkage int vprintk_emit(int facility, int level, const char *dict, size_t dictlen, @@ -1502,17 +1599,25 @@ char *text = textbuf; size_t text_len; enum log_flags lflags = 0; - unsigned long flags; + unsigned long flags = 0; int this_cpu; int printed_len = 0; - - boot_delay_msec(level); - printk_delay(); - - /* This stops the holder of console_sem just where we want him */ - local_irq_save(flags); - this_cpu = smp_processor_id(); - +#if defined(CONFIG_AVM_DEBUG) && defined(CONFIG_SMP) && defined(CONFIG_MIPS) + int yield_context = is_yield_context(); +#else +#define yield_context 0 +#endif/*--- #if defined(CONFIG_AVM_DEBUG) ---*/ + this_cpu = raw_smp_processor_id(); + + if(!yield_context) { + boot_delay_msec(level); + printk_delay(); + + /* This stops the holder of console_sem just where we want him */ + yield_local_irq_save(flags); + } else { + this_cpu |= ((yield_context - 1) << 8); + } /* * Ouch, printk recursed into itself! */ @@ -1531,8 +1636,10 @@ zap_locks(); } - lockdep_off(); - raw_spin_lock(&logbuf_lock); + if(!yield_context) { + lockdep_off(); + } + yield_raw_spin_lock(&logbuf_lock); logbuf_cpu = this_cpu; if (recursion_bug) { @@ -1557,6 +1664,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/*--- #if defined(CONFIG_AVM_ENHANCED) ---*/ /* strip kernel syslog prefix and extract log level or control flags */ if (facility == 0) { @@ -1581,6 +1696,17 @@ if (level == -1) level = default_message_loglevel; +#if !defined(CONFIG_AVM_IPI_YIELD) + /*---- landet leider nur in dev/debug-Buffer - nicht im CRV! ----*/ + if(yield_context) { + /*--- output from yield (nonlinux!) goes never over the standard-console (except see above) ! ---*/ + printed_len = print_yield_output(level, this_cpu, text, text_len, lflags); + logbuf_cpu = UINT_MAX; + yield_raw_spin_unlock(&logbuf_lock); + return printed_len; + } +#endif/*--- #if !defined(CONFIG_AVM_IPI_YIELD) ---*/ + if (dict) lflags |= LOG_PREFIX|LOG_NEWLINE; @@ -1590,10 +1716,18 @@ * or another task also prints continuation lines. */ if (cont.len && (lflags & LOG_PREFIX || cont.owner != current)) - cont_flush(LOG_NEWLINE); + cont_flush(LOG_NEWLINE +#if defined(CONFIG_AVM_DEBUG) + | (lflags & LOG_PRINTK_AVM) +#endif/*--- #if defined(CONFIG_AVM_DEBUG) ---*/ + ); /* buffer line if possible, otherwise store it right away */ - if (!cont_add(facility, level, text, text_len)) + if (!cont_add( +#if defined(CONFIG_AVM_DEBUG) + (lflags & LOG_PRINTK_AVM), +#endif/*--- #if defined(CONFIG_AVM_DEBUG) ---*/ + facility, level, text, text_len)) log_store(facility, level, lflags | LOG_CONT, 0, dict, dictlen, text, text_len); } else { @@ -1607,8 +1741,16 @@ */ if (cont.len && cont.owner == current) { if (!(lflags & LOG_PREFIX)) - stored = cont_add(facility, level, text, text_len); - cont_flush(LOG_NEWLINE); + stored = cont_add( +#if defined(CONFIG_AVM_DEBUG) + (lflags & LOG_PRINTK_AVM), +#endif/*--- #if defined(CONFIG_AVM_DEBUG) ---*/ + facility, level, text, text_len); + cont_flush(LOG_NEWLINE +#if defined(CONFIG_AVM_DEBUG) + | (lflags & LOG_PRINTK_AVM) +#endif/*--- #if defined(CONFIG_AVM_DEBUG) ---*/ + ); } if (!stored) @@ -1625,20 +1767,25 @@ * The console_trylock_for_printk() function will release 'logbuf_lock' * regardless of whether it actually gets the console semaphore or not. */ +#if defined(CONFIG_AVM_DEBUG) + if(yield_context) { + /*--- fuer console_trylock_for_printk die korrekte cpu ---*/ + this_cpu &= 0xFF; + } +#endif/*--- #if defined(CONFIG_AVM_DEBUG) ---*/ if (console_trylock_for_printk(this_cpu)) console_unlock(); - lockdep_on(); + lockdep_on(); out_restore_irqs: - local_irq_restore(flags); - + yield_local_irq_restore(flags); return printed_len; } EXPORT_SYMBOL(vprintk_emit); asmlinkage int vprintk(const char *fmt, va_list args) { - return vprintk_emit(0, -1, NULL, 0, fmt, args); + return vprintk_emit( 0, -1, NULL, 0, fmt, args); } EXPORT_SYMBOL(vprintk); @@ -1650,7 +1797,7 @@ int r; va_start(args, fmt); - r = vprintk_emit(facility, level, dict, dictlen, fmt, args); + r = vprintk_emit( facility, level, dict, dictlen, fmt, args); va_end(args); return r; @@ -1692,13 +1839,46 @@ } #endif va_start(args, fmt); - r = vprintk_emit(0, -1, NULL, 0, fmt, args); + r = vprintk_emit( 0 , -1, NULL, 0, fmt, args); va_end(args); return r; } 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 @@ -1721,11 +1901,22 @@ } cont; static struct log *log_from_idx(u32 idx) { return NULL; } static u32 log_next(u32 idx) { return 0; } -static void call_console_drivers(int level, const char *text, size_t len) {} +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 *text, size_t len) {} static size_t msg_print_text(const struct log *msg, enum log_flags prev, bool syslog, char *buf, size_t size) { return 0; } static size_t cont_print_text(char *text, size_t size) { return 0; } +#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 @@ -1963,18 +2154,21 @@ * exclusive 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 (yield_down_trylock(&console_sem)) return 0; if (console_suspended) { - up(&console_sem); + yield_up(&console_sem); return 0; } console_locked = 1; console_may_schedule = 0; - mutex_acquire(&console_lock_dep_map, 0, 1, _RET_IP_); + if(yield_is_linux_context()) { + mutex_acquire(&console_lock_dep_map, 0, 1, _RET_IP_); + } return 1; } EXPORT_SYMBOL(console_trylock); @@ -1984,12 +2178,15 @@ return console_locked; } +/*--------------------------------------------------------------------------------*\ + * 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; @@ -2003,14 +2200,18 @@ goto out; len = cont_print_text(text, size); - raw_spin_unlock(&logbuf_lock); - stop_critical_timings(); - call_console_drivers(cont.level, 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) ---*/ + 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); } /** @@ -2026,6 +2227,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) { @@ -2036,7 +2238,7 @@ bool do_cond_resched, retry; if (console_suspended) { - up(&console_sem); + yield_up(&console_sem); return; } @@ -2061,7 +2263,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; @@ -2101,26 +2303,32 @@ console_idx = log_next(console_idx); console_seq++; console_prev = msg->flags; - raw_spin_unlock(&logbuf_lock); + yield_raw_spin_unlock(&logbuf_lock); - stop_critical_timings(); /* don't trace print latency */ - call_console_drivers(level, 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) ---*/ + text, len); + yield_start_critical_timings(); + yield_local_irq_restore(flags); if (do_cond_resched) cond_resched(); } console_locked = 0; - mutex_release(&console_lock_dep_map, 1, _RET_IP_); + if(yield_is_linux_context()) { + mutex_release(&console_lock_dep_map, 1, _RET_IP_); + } /* Release the exclusive_console once it is used */ if (unlikely(exclusive_console)) exclusive_console = NULL; - raw_spin_unlock(&logbuf_lock); + yield_raw_spin_unlock(&logbuf_lock); - up(&console_sem); + yield_up(&console_sem); /* * Someone could have filled up the buffer again, so re-check if there's @@ -2128,14 +2336,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); @@ -2581,6 +2789,25 @@ 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