Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4bb0057f authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'core/printk' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/linux-2.6-tip:
  x86, generic: mark early_printk as asmlinkage
  printk: export console_drivers
  printk: remember the message level for multi-line output
  printk: refactor processing of line severity tokens
  printk: don't prefer unsuited consoles on registration
  printk: clean up recursion check related static variables
  namespacecheck: more kernel/printk.c fixes
  namespacecheck: fix kernel printk.c
parents 116a9fb3 9e4144ab
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -196,7 +196,7 @@ static struct console simnow_console = {
static struct console *early_console = &early_vga_console;
static struct console *early_console = &early_vga_console;
static int early_console_initialized;
static int early_console_initialized;


void early_printk(const char *fmt, ...)
asmlinkage void early_printk(const char *fmt, ...)
{
{
	char buf[512];
	char buf[512];
	int n;
	int n;
+1 −7
Original line number Original line Diff line number Diff line
@@ -187,9 +187,6 @@ asmlinkage int vprintk(const char *fmt, va_list args)
	__attribute__ ((format (printf, 1, 0)));
	__attribute__ ((format (printf, 1, 0)));
asmlinkage int printk(const char * fmt, ...)
asmlinkage int printk(const char * fmt, ...)
	__attribute__ ((format (printf, 1, 2))) __cold;
	__attribute__ ((format (printf, 1, 2))) __cold;
extern int log_buf_get_len(void);
extern int log_buf_read(int idx);
extern int log_buf_copy(char *dest, int idx, int len);


extern int printk_ratelimit_jiffies;
extern int printk_ratelimit_jiffies;
extern int printk_ratelimit_burst;
extern int printk_ratelimit_burst;
@@ -205,9 +202,6 @@ static inline int vprintk(const char *s, va_list args) { return 0; }
static inline int printk(const char *s, ...)
static inline int printk(const char *s, ...)
	__attribute__ ((format (printf, 1, 2)));
	__attribute__ ((format (printf, 1, 2)));
static inline int __cold printk(const char *s, ...) { return 0; }
static inline int __cold printk(const char *s, ...) { return 0; }
static inline int log_buf_get_len(void) { return 0; }
static inline int log_buf_read(int idx) { return 0; }
static inline int log_buf_copy(char *dest, int idx, int len) { return 0; }
static inline int printk_ratelimit(void) { return 0; }
static inline int printk_ratelimit(void) { return 0; }
static inline int __printk_ratelimit(int ratelimit_jiffies, \
static inline int __printk_ratelimit(int ratelimit_jiffies, \
				     int ratelimit_burst) { return 0; }
				     int ratelimit_burst) { return 0; }
@@ -216,7 +210,7 @@ static inline bool printk_timed_ratelimit(unsigned long *caller_jiffies, \
		{ return false; }
		{ return false; }
#endif
#endif


extern void __attribute__((format(printf, 1, 2)))
extern void asmlinkage __attribute__((format(printf, 1, 2)))
	early_printk(const char *fmt, ...);
	early_printk(const char *fmt, ...);


unsigned long int_sqrt(unsigned long);
unsigned long int_sqrt(unsigned long);
+43 −62
Original line number Original line Diff line number Diff line
@@ -38,7 +38,7 @@
/*
/*
 * Architectures can override it:
 * Architectures can override it:
 */
 */
void __attribute__((weak)) early_printk(const char *fmt, ...)
void asmlinkage __attribute__((weak)) early_printk(const char *fmt, ...)
{
{
}
}


@@ -235,7 +235,7 @@ static inline void boot_delay_msec(void)
/*
/*
 * Return the number of unread characters in the log buffer.
 * Return the number of unread characters in the log buffer.
 */
 */
int log_buf_get_len(void)
static int log_buf_get_len(void)
{
{
	return logged_chars;
	return logged_chars;
}
}
@@ -271,19 +271,6 @@ int log_buf_copy(char *dest, int idx, int len)
	return ret;
	return ret;
}
}


/*
 * Extract a single character from the log buffer.
 */
int log_buf_read(int idx)
{
	char ret;

	if (log_buf_copy(&ret, idx, 1) == 1)
		return ret;
	else
		return -1;
}

/*
/*
 * Commands to do_syslog:
 * Commands to do_syslog:
 *
 *
@@ -669,18 +656,17 @@ static int acquire_console_semaphore_for_printk(unsigned int cpu)
	spin_unlock(&logbuf_lock);
	spin_unlock(&logbuf_lock);
	return retval;
	return retval;
}
}

static const char recursion_bug_msg [] =
static const char printk_recursion_bug_msg [] =
		KERN_CRIT "BUG: recent printk recursion!\n";
		KERN_CRIT "BUG: recent printk recursion!\n";
static int printk_recursion_bug;
static int recursion_bug;
	static int new_text_line = 1;
static char printk_buf[1024];


asmlinkage int vprintk(const char *fmt, va_list args)
asmlinkage int vprintk(const char *fmt, va_list args)
{
{
	static int log_level_unknown = 1;
	static char printk_buf[1024];

	unsigned long flags;
	int printed_len = 0;
	int printed_len = 0;
	int current_log_level = default_message_loglevel;
	unsigned long flags;
	int this_cpu;
	int this_cpu;
	char *p;
	char *p;


@@ -703,7 +689,7 @@ asmlinkage int vprintk(const char *fmt, va_list args)
		 * it can be printed at the next appropriate moment:
		 * it can be printed at the next appropriate moment:
		 */
		 */
		if (!oops_in_progress) {
		if (!oops_in_progress) {
			printk_recursion_bug = 1;
			recursion_bug = 1;
			goto out_restore_irqs;
			goto out_restore_irqs;
		}
		}
		zap_locks();
		zap_locks();
@@ -713,70 +699,62 @@ asmlinkage int vprintk(const char *fmt, va_list args)
	spin_lock(&logbuf_lock);
	spin_lock(&logbuf_lock);
	printk_cpu = this_cpu;
	printk_cpu = this_cpu;


	if (printk_recursion_bug) {
	if (recursion_bug) {
		printk_recursion_bug = 0;
		recursion_bug = 0;
		strcpy(printk_buf, printk_recursion_bug_msg);
		strcpy(printk_buf, recursion_bug_msg);
		printed_len = sizeof(printk_recursion_bug_msg);
		printed_len = sizeof(recursion_bug_msg);
	}
	}
	/* Emit the output into the temporary buffer */
	/* Emit the output into the temporary buffer */
	printed_len += vscnprintf(printk_buf + printed_len,
	printed_len += vscnprintf(printk_buf + printed_len,
				  sizeof(printk_buf) - printed_len, fmt, args);
				  sizeof(printk_buf) - printed_len, fmt, args);



	/*
	/*
	 * Copy the output into log_buf.  If the caller didn't provide
	 * Copy the output into log_buf.  If the caller didn't provide
	 * appropriate log level tags, we insert them here
	 * appropriate log level tags, we insert them here
	 */
	 */
	for (p = printk_buf; *p; p++) {
	for (p = printk_buf; *p; p++) {
		if (log_level_unknown) {
		if (new_text_line) {
                        /* log_level_unknown signals the start of a new line */
			/* If a token, set current_log_level and skip over */
			if (p[0] == '<' && p[1] >= '0' && p[1] <= '7' &&
			    p[2] == '>') {
				current_log_level = p[1] - '0';
				p += 3;
				printed_len -= 3;
			}

			/* Always output the token */
			emit_log_char('<');
			emit_log_char(current_log_level + '0');
			emit_log_char('>');
			printed_len += 3;
			new_text_line = 0;

			if (printk_time) {
			if (printk_time) {
				int loglev_char;
				/* Follow the token with the time */
				char tbuf[50], *tp;
				char tbuf[50], *tp;
				unsigned tlen;
				unsigned tlen;
				unsigned long long t;
				unsigned long long t;
				unsigned long nanosec_rem;
				unsigned long nanosec_rem;


				/*
				 * force the log level token to be
				 * before the time output.
				 */
				if (p[0] == '<' && p[1] >='0' &&
				   p[1] <= '7' && p[2] == '>') {
					loglev_char = p[1];
					p += 3;
					printed_len -= 3;
				} else {
					loglev_char = default_message_loglevel
						+ '0';
				}
				t = cpu_clock(printk_cpu);
				t = cpu_clock(printk_cpu);
				nanosec_rem = do_div(t, 1000000000);
				nanosec_rem = do_div(t, 1000000000);
				tlen = sprintf(tbuf,
				tlen = sprintf(tbuf, "[%5lu.%06lu] ",
						"<%c>[%5lu.%06lu] ",
						loglev_char,
						(unsigned long) t,
						(unsigned long) t,
						nanosec_rem / 1000);
						nanosec_rem / 1000);


				for (tp = tbuf; tp < tbuf + tlen; tp++)
				for (tp = tbuf; tp < tbuf + tlen; tp++)
					emit_log_char(*tp);
					emit_log_char(*tp);
				printed_len += tlen;
				printed_len += tlen;
			} else {
				if (p[0] != '<' || p[1] < '0' ||
				   p[1] > '7' || p[2] != '>') {
					emit_log_char('<');
					emit_log_char(default_message_loglevel
						+ '0');
					emit_log_char('>');
					printed_len += 3;
			}
			}
			}

			log_level_unknown = 0;
			if (!*p)
			if (!*p)
				break;
				break;
		}
		}

		emit_log_char(*p);
		emit_log_char(*p);
		if (*p == '\n')
		if (*p == '\n')
			log_level_unknown = 1;
			new_text_line = 1;
	}
	}


	/*
	/*
@@ -1179,10 +1157,13 @@ void register_console(struct console *console)
			console->index = 0;
			console->index = 0;
		if (console->setup == NULL ||
		if (console->setup == NULL ||
		    console->setup(console, NULL) == 0) {
		    console->setup(console, NULL) == 0) {
			console->flags |= CON_ENABLED | CON_CONSDEV;
			console->flags |= CON_ENABLED;
			if (console->device) {
				console->flags |= CON_CONSDEV;
				preferred_console = 0;
				preferred_console = 0;
			}
			}
		}
		}
	}


	/*
	/*
	 *	See if this console matches one we selected on
	 *	See if this console matches one we selected on