Skip to content

Commit da34b03

Browse files
committed
Merge branch 'for-5.13-vsprintf-pgp' into for-linus
2 parents 84696cf + c244297 commit da34b03

File tree

4 files changed

+149
-22
lines changed

4 files changed

+149
-22
lines changed

Documentation/core-api/printk-formats.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -564,7 +564,7 @@ Flags bitfields such as page flags, gfp_flags
564564

565565
::
566566

567-
%pGp referenced|uptodate|lru|active|private
567+
%pGp referenced|uptodate|lru|active|private|node=0|zone=2|lastcpupid=0x1fffff
568568
%pGg GFP_USER|GFP_DMA32|GFP_NOWARN
569569
%pGv read|exec|mayread|maywrite|mayexec|denywrite
570570

lib/test_printf.c

Lines changed: 80 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -577,24 +577,98 @@ netdev_features(void)
577577
{
578578
}
579579

580+
struct page_flags_test {
581+
int width;
582+
int shift;
583+
int mask;
584+
unsigned long value;
585+
const char *fmt;
586+
const char *name;
587+
};
588+
589+
static struct page_flags_test pft[] = {
590+
{SECTIONS_WIDTH, SECTIONS_PGSHIFT, SECTIONS_MASK,
591+
0, "%d", "section"},
592+
{NODES_WIDTH, NODES_PGSHIFT, NODES_MASK,
593+
0, "%d", "node"},
594+
{ZONES_WIDTH, ZONES_PGSHIFT, ZONES_MASK,
595+
0, "%d", "zone"},
596+
{LAST_CPUPID_WIDTH, LAST_CPUPID_PGSHIFT, LAST_CPUPID_MASK,
597+
0, "%#x", "lastcpupid"},
598+
{KASAN_TAG_WIDTH, KASAN_TAG_PGSHIFT, KASAN_TAG_MASK,
599+
0, "%#x", "kasantag"},
600+
};
601+
602+
static void __init
603+
page_flags_test(int section, int node, int zone, int last_cpupid,
604+
int kasan_tag, int flags, const char *name, char *cmp_buf)
605+
{
606+
unsigned long values[] = {section, node, zone, last_cpupid, kasan_tag};
607+
unsigned long page_flags = 0;
608+
unsigned long size = 0;
609+
bool append = false;
610+
int i;
611+
612+
flags &= BIT(NR_PAGEFLAGS) - 1;
613+
if (flags) {
614+
page_flags |= flags;
615+
snprintf(cmp_buf + size, BUF_SIZE - size, "%s", name);
616+
size = strlen(cmp_buf);
617+
#if SECTIONS_WIDTH || NODES_WIDTH || ZONES_WIDTH || \
618+
LAST_CPUPID_WIDTH || KASAN_TAG_WIDTH
619+
/* Other information also included in page flags */
620+
snprintf(cmp_buf + size, BUF_SIZE - size, "|");
621+
size = strlen(cmp_buf);
622+
#endif
623+
}
624+
625+
/* Set the test value */
626+
for (i = 0; i < ARRAY_SIZE(pft); i++)
627+
pft[i].value = values[i];
628+
629+
for (i = 0; i < ARRAY_SIZE(pft); i++) {
630+
if (!pft[i].width)
631+
continue;
632+
633+
if (append) {
634+
snprintf(cmp_buf + size, BUF_SIZE - size, "|");
635+
size = strlen(cmp_buf);
636+
}
637+
638+
page_flags |= (pft[i].value & pft[i].mask) << pft[i].shift;
639+
snprintf(cmp_buf + size, BUF_SIZE - size, "%s=", pft[i].name);
640+
size = strlen(cmp_buf);
641+
snprintf(cmp_buf + size, BUF_SIZE - size, pft[i].fmt,
642+
pft[i].value & pft[i].mask);
643+
size = strlen(cmp_buf);
644+
append = true;
645+
}
646+
647+
test(cmp_buf, "%pGp", &page_flags);
648+
}
649+
580650
static void __init
581651
flags(void)
582652
{
583653
unsigned long flags;
584-
gfp_t gfp;
585654
char *cmp_buffer;
655+
gfp_t gfp;
656+
657+
cmp_buffer = kmalloc(BUF_SIZE, GFP_KERNEL);
658+
if (!cmp_buffer)
659+
return;
586660

587661
flags = 0;
588-
test("", "%pGp", &flags);
662+
page_flags_test(0, 0, 0, 0, 0, flags, "", cmp_buffer);
589663

590-
/* Page flags should filter the zone id */
591664
flags = 1UL << NR_PAGEFLAGS;
592-
test("", "%pGp", &flags);
665+
page_flags_test(0, 0, 0, 0, 0, flags, "", cmp_buffer);
593666

594667
flags |= 1UL << PG_uptodate | 1UL << PG_dirty | 1UL << PG_lru
595668
| 1UL << PG_active | 1UL << PG_swapbacked;
596-
test("uptodate|dirty|lru|active|swapbacked", "%pGp", &flags);
597-
669+
page_flags_test(1, 1, 1, 0x1fffff, 1, flags,
670+
"uptodate|dirty|lru|active|swapbacked",
671+
cmp_buffer);
598672

599673
flags = VM_READ | VM_EXEC | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC
600674
| VM_DENYWRITE;
@@ -609,10 +683,6 @@ flags(void)
609683
gfp = __GFP_ATOMIC;
610684
test("__GFP_ATOMIC", "%pGg", &gfp);
611685

612-
cmp_buffer = kmalloc(BUF_SIZE, GFP_KERNEL);
613-
if (!cmp_buffer)
614-
return;
615-
616686
/* Any flags not translated by the table should remain numeric */
617687
gfp = ~__GFP_BITS_MASK;
618688
snprintf(cmp_buffer, BUF_SIZE, "%#lx", (unsigned long) gfp);

lib/vsprintf.c

Lines changed: 61 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1916,6 +1916,66 @@ char *format_flags(char *buf, char *end, unsigned long flags,
19161916
return buf;
19171917
}
19181918

1919+
struct page_flags_fields {
1920+
int width;
1921+
int shift;
1922+
int mask;
1923+
const struct printf_spec *spec;
1924+
const char *name;
1925+
};
1926+
1927+
static const struct page_flags_fields pff[] = {
1928+
{SECTIONS_WIDTH, SECTIONS_PGSHIFT, SECTIONS_MASK,
1929+
&default_dec_spec, "section"},
1930+
{NODES_WIDTH, NODES_PGSHIFT, NODES_MASK,
1931+
&default_dec_spec, "node"},
1932+
{ZONES_WIDTH, ZONES_PGSHIFT, ZONES_MASK,
1933+
&default_dec_spec, "zone"},
1934+
{LAST_CPUPID_WIDTH, LAST_CPUPID_PGSHIFT, LAST_CPUPID_MASK,
1935+
&default_flag_spec, "lastcpupid"},
1936+
{KASAN_TAG_WIDTH, KASAN_TAG_PGSHIFT, KASAN_TAG_MASK,
1937+
&default_flag_spec, "kasantag"},
1938+
};
1939+
1940+
static
1941+
char *format_page_flags(char *buf, char *end, unsigned long flags)
1942+
{
1943+
unsigned long main_flags = flags & (BIT(NR_PAGEFLAGS) - 1);
1944+
bool append = false;
1945+
int i;
1946+
1947+
/* Page flags from the main area. */
1948+
if (main_flags) {
1949+
buf = format_flags(buf, end, main_flags, pageflag_names);
1950+
append = true;
1951+
}
1952+
1953+
/* Page flags from the fields area */
1954+
for (i = 0; i < ARRAY_SIZE(pff); i++) {
1955+
/* Skip undefined fields. */
1956+
if (!pff[i].width)
1957+
continue;
1958+
1959+
/* Format: Flag Name + '=' (equals sign) + Number + '|' (separator) */
1960+
if (append) {
1961+
if (buf < end)
1962+
*buf = '|';
1963+
buf++;
1964+
}
1965+
1966+
buf = string(buf, end, pff[i].name, default_str_spec);
1967+
if (buf < end)
1968+
*buf = '=';
1969+
buf++;
1970+
buf = number(buf, end, (flags >> pff[i].shift) & pff[i].mask,
1971+
*pff[i].spec);
1972+
1973+
append = true;
1974+
}
1975+
1976+
return buf;
1977+
}
1978+
19191979
static noinline_for_stack
19201980
char *flags_string(char *buf, char *end, void *flags_ptr,
19211981
struct printf_spec spec, const char *fmt)
@@ -1928,11 +1988,7 @@ char *flags_string(char *buf, char *end, void *flags_ptr,
19281988

19291989
switch (fmt[1]) {
19301990
case 'p':
1931-
flags = *(unsigned long *)flags_ptr;
1932-
/* Remove zone id */
1933-
flags &= (1UL << NR_PAGEFLAGS) - 1;
1934-
names = pageflag_names;
1935-
break;
1991+
return format_page_flags(buf, end, *(unsigned long *)flags_ptr);
19361992
case 'v':
19371993
flags = *(unsigned long *)flags_ptr;
19381994
names = vmaflag_names;

mm/slub.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -615,7 +615,7 @@ static void print_track(const char *s, struct track *t, unsigned long pr_time)
615615
if (!t->addr)
616616
return;
617617

618-
pr_err("INFO: %s in %pS age=%lu cpu=%u pid=%d\n",
618+
pr_err("%s in %pS age=%lu cpu=%u pid=%d\n",
619619
s, (void *)t->addr, pr_time - t->when, t->cpu, t->pid);
620620
#ifdef CONFIG_STACKTRACE
621621
{
@@ -641,8 +641,9 @@ void print_tracking(struct kmem_cache *s, void *object)
641641

642642
static void print_page_info(struct page *page)
643643
{
644-
pr_err("INFO: Slab 0x%p objects=%u used=%u fp=0x%p flags=0x%04lx\n",
645-
page, page->objects, page->inuse, page->freelist, page->flags);
644+
pr_err("Slab 0x%p objects=%u used=%u fp=0x%p flags=%#lx(%pGp)\n",
645+
page, page->objects, page->inuse, page->freelist,
646+
page->flags, &page->flags);
646647

647648
}
648649

@@ -697,7 +698,7 @@ static void print_trailer(struct kmem_cache *s, struct page *page, u8 *p)
697698

698699
print_page_info(page);
699700

700-
pr_err("INFO: Object 0x%p @offset=%tu fp=0x%p\n\n",
701+
pr_err("Object 0x%p @offset=%tu fp=0x%p\n\n",
701702
p, p - addr, get_freepointer(s, p));
702703

703704
if (s->flags & SLAB_RED_ZONE)
@@ -790,7 +791,7 @@ static int check_bytes_and_report(struct kmem_cache *s, struct page *page,
790791
end--;
791792

792793
slab_bug(s, "%s overwritten", what);
793-
pr_err("INFO: 0x%p-0x%p @offset=%tu. First byte 0x%x instead of 0x%x\n",
794+
pr_err("0x%p-0x%p @offset=%tu. First byte 0x%x instead of 0x%x\n",
794795
fault, end - 1, fault - addr,
795796
fault[0], value);
796797
print_trailer(s, page, object);
@@ -3868,7 +3869,7 @@ static void list_slab_objects(struct kmem_cache *s, struct page *page,
38683869
for_each_object(p, s, addr, page->objects) {
38693870

38703871
if (!test_bit(__obj_to_index(s, addr, p), map)) {
3871-
pr_err("INFO: Object 0x%p @offset=%tu\n", p, p - addr);
3872+
pr_err("Object 0x%p @offset=%tu\n", p, p - addr);
38723873
print_tracking(s, p);
38733874
}
38743875
}

0 commit comments

Comments
 (0)