#define S_SIZE (1024 - (sizeof(unsigned int) + 1)) struct sbuff { unsigned int count; char buf[S_SIZE + 1]; }; static struct sbuff emergency, *emergency_ptr = &emergency; static int sb_add(struct sbuff *m, const char *f, ...) { va_list args; int len; if (likely(m->count < S_SIZE)) { va_start(args, f); len = vsnprintf(m->buf + m->count, S_SIZE - m->count, f, args); va_end(args); if (likely(m->count + len < S_SIZE)) { m->count += len; return 0; } } m->count = S_SIZE; printk_once(KERN_ERR KBUILD_MODNAME " please increase S_SIZE\n"); return -1; } static struct sbuff *sb_open(void) { struct sbuff *m = kmalloc(sizeof(*m), GFP_ATOMIC); if (unlikely(!m)) { local_bh_disable(); do { m = xchg(&emergency_ptr, NULL); } while (!m); } m->count = 0; return m; } static void sb_close(struct sbuff *m) { m->buf[m->count] = 0; printk("%s\n", m->buf); if (likely(m != &emergency)) kfree(m); else { xchg(&emergency_ptr, m); local_bh_enable(); } }