Commit b66cb4f1 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull printk updates from Petr Mladek:

 - Fix printk ring buffer initialization and sanity checks

 - Workaround printf kunit test compilation with gcc < 12.1

 - Add IPv6 address printf format tests

 - Misc code and documentation cleanup

* tag 'printk-for-7.1' of git://git.kernel.org/pub/scm/linux/kernel/git/printk/linux:
  printf: Compile the kunit test with DISABLE_BRANCH_PROFILING DISABLE_BRANCH_PROFILING
  lib/vsprintf: use bool for local decode variable
  lib/hexdump: print_hex_dump_bytes() calls print_hex_dump_debug()
  printk: ringbuffer: fix errors in comments
  printk_ringbuffer: Add sanity check for 0-size data
  printk_ringbuffer: Fix get_data() size sanity check
  printf: add IPv6 address format tests
  printk: Fix _DESCS_COUNT type for 64-bit systems
parents ccbc9fdb add9d911
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -815,7 +815,8 @@ static inline void print_hex_dump_devel(const char *prefix_str, int prefix_type,
#endif

/**
 * print_hex_dump_bytes - shorthand form of print_hex_dump() with default params
 * print_hex_dump_bytes - shorthand form of print_hex_dump_debug() with default
 *                        params
 * @prefix_str: string to prefix each line with;
 *  caller supplies trailing spaces for alignment if desired
 * @prefix_type: controls whether prefix of an offset, address, or none
@@ -823,7 +824,7 @@ static inline void print_hex_dump_devel(const char *prefix_str, int prefix_type,
 * @buf: data blob to dump
 * @len: number of bytes in the @buf
 *
 * Calls print_hex_dump(), with log level of KERN_DEBUG,
 * Calls print_hex_dump_debug(), with log level of KERN_DEBUG,
 * rowsize of 16, groupsize of 1, and ASCII output included.
 */
#define print_hex_dump_bytes(prefix_str, prefix_type, buf, len)	\
+15 −12
Original line number Diff line number Diff line
@@ -14,7 +14,7 @@
 *
 * Data Structure
 * --------------
 * The printk_ringbuffer is made up of 3 internal ringbuffers:
 * The printk_ringbuffer is made up of 2 internal ringbuffers:
 *
 *   desc_ring
 *     A ring of descriptors and their meta data (such as sequence number,
@@ -224,7 +224,7 @@
 *
 *	prb_rec_init_rd(&r, &info, &text_buf[0], sizeof(text_buf));
 *
 *	prb_for_each_record(0, &test_rb, &seq, &r) {
 *	prb_for_each_record(0, &test_rb, seq, &r) {
 *		if (info.seq != seq)
 *			pr_warn("lost %llu records\n", info.seq - seq);
 *
@@ -1302,23 +1302,26 @@ static const char *get_data(struct prb_data_ring *data_ring,
		return NULL;
	}

	/* Sanity check. Data-less blocks were handled earlier. */
	if (WARN_ON_ONCE(!data_check_size(data_ring, *data_size) || !*data_size))
		return NULL;

	/* A valid data block will always be aligned to the ID size. */
	if (WARN_ON_ONCE(blk_lpos->begin != ALIGN(blk_lpos->begin, sizeof(db->id))) ||
	    WARN_ON_ONCE(blk_lpos->next != ALIGN(blk_lpos->next, sizeof(db->id)))) {
		return NULL;
	}

	/* A valid data block will always have at least an ID. */
	if (WARN_ON_ONCE(*data_size < sizeof(db->id)))
	/*
	 * A regular data block will always have an ID and at least
	 * 1 byte of data. Data-less blocks were handled earlier.
	 */
	if (WARN_ON_ONCE(*data_size <= sizeof(db->id)))
		return NULL;

	/* Subtract block ID space from size to reflect data size. */
	*data_size -= sizeof(db->id);

	/* Sanity check the max size of the regular data block. */
	if (WARN_ON_ONCE(!data_check_size(data_ring, *data_size)))
		return NULL;

	return &db->data[0];
}

@@ -1365,7 +1368,7 @@ static struct prb_desc *desc_reopen_last(struct prb_desc_ring *desc_ring,
	 *
	 * WMB from _prb_commit:A to _prb_commit:B
	 *    matching
	 * MB If desc_reopen_last:A to prb_reserve_in_last:A
	 * MB from desc_reopen_last:A to prb_reserve_in_last:A
	 */
	if (!atomic_long_try_cmpxchg(&d->state_var, &prev_state_val,
			DESC_SV(id, desc_reserved))) { /* LMM(desc_reopen_last:A) */
@@ -1770,9 +1773,9 @@ static void _prb_commit(struct prb_reserved_entry *e, unsigned long state_val)
	 *
	 *    Relies on:
	 *
	 *    MB _prb_commit:B to prb_commit:A
	 *    MB from _prb_commit:B to prb_commit:A
	 *       matching
	 *    MB desc_reserve:D to desc_make_final:A
	 *    MB from desc_reserve:D to desc_make_final:A
	 */
	if (!atomic_long_try_cmpxchg(&d->state_var, &prev_state_val,
			DESC_SV(e->id, state_val))) { /* LMM(_prb_commit:B) */
@@ -2035,7 +2038,7 @@ u64 prb_first_seq(struct printk_ringbuffer *rb)
		 *
		 * MB from desc_push_tail:B to desc_reserve:F
		 *    matching
		 * RMB prb_first_seq:B to prb_first_seq:A
		 * RMB from prb_first_seq:B to prb_first_seq:A
		 */
		smp_rmb(); /* LMM(prb_first_seq:C) */
	}
+2 −2
Original line number Diff line number Diff line
@@ -127,7 +127,7 @@ enum desc_state {
};

#define _DATA_SIZE(sz_bits)	(1UL << (sz_bits))
#define _DESCS_COUNT(ct_bits)	(1U << (ct_bits))
#define _DESCS_COUNT(ct_bits)	(1UL << (ct_bits))
#define DESC_SV_BITS		BITS_PER_LONG
#define DESC_FLAGS_SHIFT	(DESC_SV_BITS - 2)
#define DESC_FLAGS_MASK		(3UL << DESC_FLAGS_SHIFT)
@@ -388,7 +388,7 @@ for ((s) = from; prb_read_valid(rb, s, r); (s) = (r)->info->seq + 1)
 *
 * This is a macro for conveniently iterating over a ringbuffer.
 * Note that @s may not be the sequence number of the record on each
 * iteration. For the sequence number, @r->info->seq should be checked.
 * iteration. For the sequence number, @i->seq should be checked.
 *
 * Context: Any context.
 */
+2 −0
Original line number Diff line number Diff line
@@ -40,6 +40,8 @@ obj-$(CONFIG_MEMCPY_KUNIT_TEST) += memcpy_kunit.o
obj-$(CONFIG_MIN_HEAP_KUNIT_TEST) += min_heap_kunit.o
CFLAGS_overflow_kunit.o = $(call cc-disable-warning, tautological-constant-out-of-range-compare)
obj-$(CONFIG_OVERFLOW_KUNIT_TEST) += overflow_kunit.o
# GCC < 12.1 can miscompile errptr() test when branch profiling is enabled.
CFLAGS_printf_kunit.o += -DDISABLE_BRANCH_PROFILING
obj-$(CONFIG_PRINTF_KUNIT_TEST) += printf_kunit.o
obj-$(CONFIG_RANDSTRUCT_KUNIT_TEST) += randstruct_kunit.o
obj-$(CONFIG_SCANF_KUNIT_TEST) += scanf_kunit.o
+22 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include <linux/dcache.h>
#include <linux/socket.h>
#include <linux/in.h>
#include <linux/in6.h>

#include <linux/gfp.h>
#include <linux/mm.h>
@@ -437,6 +438,27 @@ ip4(struct kunit *kunittest)
static void
ip6(struct kunit *kunittest)
{
	const struct in6_addr addr = {
		.s6_addr = { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04,
			     0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 }
	};
	const struct in6_addr single_zero = {
		.s6_addr = { 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x04,
			     0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 }
	};
	struct sockaddr_in6 sa = {
		.sin6_family = AF_INET6,
		.sin6_port = cpu_to_be16(12345),
		.sin6_addr = addr,
	};

	test("00010002000300040005000600070008|0001:0002:0003:0004:0005:0006:0007:0008",
	     "%pi6|%pI6", &addr, &addr);
	test("00010002000300040005000600070008|0001:0002:0003:0004:0005:0006:0007:0008",
	     "%piS|%pIS", &sa, &sa);
	test("1:2:3:4:5:6:7:8", "%pI6c", &addr);
	test("1:0:3:4:5:6:7:8", "%pI6c", &single_zero);
	test("[1:2:3:4:5:6:7:8]:12345", "%pISpc", &sa);
}

static void
Loading