Merge branch 'tracing/urgent' into tracing/core
Merge reason: Pick up latest fixes and update to latest upstream. Signed-off-by: Ingo Molnar <mingo@elte.hu>
This commit is contained in:
@@ -50,6 +50,14 @@ config MAGIC_SYSRQ
|
||||
keys are documented in <file:Documentation/sysrq.txt>. Don't say Y
|
||||
unless you really know what this hack does.
|
||||
|
||||
config STRIP_ASM_SYMS
|
||||
bool "Strip assembler-generated symbols during link"
|
||||
default n
|
||||
help
|
||||
Strip internal assembler-generated symbols during a link (symbols
|
||||
that look like '.Lxxx') so they don't pollute the output of
|
||||
get_wchan() and suchlike.
|
||||
|
||||
config UNUSED_SYMBOLS
|
||||
bool "Enable unused/obsolete exported symbols"
|
||||
default y if X86
|
||||
|
@@ -1,6 +1,8 @@
|
||||
config HAVE_ARCH_KMEMCHECK
|
||||
bool
|
||||
|
||||
if HAVE_ARCH_KMEMCHECK
|
||||
|
||||
menuconfig KMEMCHECK
|
||||
bool "kmemcheck: trap use of uninitialized memory"
|
||||
depends on DEBUG_KERNEL
|
||||
@@ -89,3 +91,4 @@ config KMEMCHECK_BITOPS_OK
|
||||
accesses where not all the bits are initialized at the same time.
|
||||
This may also hide some real bugs.
|
||||
|
||||
endif
|
||||
|
@@ -27,6 +27,11 @@
|
||||
|
||||
#define GZIP_IOBUF_SIZE (16*1024)
|
||||
|
||||
static int nofill(void *buffer, unsigned int len)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Included from initramfs et al code */
|
||||
STATIC int INIT gunzip(unsigned char *buf, int len,
|
||||
int(*fill)(void*, unsigned int),
|
||||
@@ -76,6 +81,9 @@ STATIC int INIT gunzip(unsigned char *buf, int len,
|
||||
goto gunzip_nomem4;
|
||||
}
|
||||
|
||||
if (!fill)
|
||||
fill = nofill;
|
||||
|
||||
if (len == 0)
|
||||
len = fill(zbuf, GZIP_IOBUF_SIZE);
|
||||
|
||||
|
@@ -82,6 +82,11 @@ struct rc {
|
||||
#define RC_MODEL_TOTAL_BITS 11
|
||||
|
||||
|
||||
static int nofill(void *buffer, unsigned int len)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Called twice: once at startup and once in rc_normalize() */
|
||||
static void INIT rc_read(struct rc *rc)
|
||||
{
|
||||
@@ -97,7 +102,10 @@ static inline void INIT rc_init(struct rc *rc,
|
||||
int (*fill)(void*, unsigned int),
|
||||
char *buffer, int buffer_size)
|
||||
{
|
||||
rc->fill = fill;
|
||||
if (fill)
|
||||
rc->fill = fill;
|
||||
else
|
||||
rc->fill = nofill;
|
||||
rc->buffer = (uint8_t *)buffer;
|
||||
rc->buffer_size = buffer_size;
|
||||
rc->buffer_end = rc->buffer + rc->buffer_size;
|
||||
|
121
lib/flex_array.c
121
lib/flex_array.c
@@ -28,23 +28,6 @@ struct flex_array_part {
|
||||
char elements[FLEX_ARRAY_PART_SIZE];
|
||||
};
|
||||
|
||||
static inline int __elements_per_part(int element_size)
|
||||
{
|
||||
return FLEX_ARRAY_PART_SIZE / element_size;
|
||||
}
|
||||
|
||||
static inline int bytes_left_in_base(void)
|
||||
{
|
||||
int element_offset = offsetof(struct flex_array, parts);
|
||||
int bytes_left = FLEX_ARRAY_BASE_SIZE - element_offset;
|
||||
return bytes_left;
|
||||
}
|
||||
|
||||
static inline int nr_base_part_ptrs(void)
|
||||
{
|
||||
return bytes_left_in_base() / sizeof(struct flex_array_part *);
|
||||
}
|
||||
|
||||
/*
|
||||
* If a user requests an allocation which is small
|
||||
* enough, we may simply use the space in the
|
||||
@@ -54,7 +37,7 @@ static inline int nr_base_part_ptrs(void)
|
||||
static inline int elements_fit_in_base(struct flex_array *fa)
|
||||
{
|
||||
int data_size = fa->element_size * fa->total_nr_elements;
|
||||
if (data_size <= bytes_left_in_base())
|
||||
if (data_size <= FLEX_ARRAY_BASE_BYTES_LEFT)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
@@ -63,6 +46,7 @@ static inline int elements_fit_in_base(struct flex_array *fa)
|
||||
* flex_array_alloc - allocate a new flexible array
|
||||
* @element_size: the size of individual elements in the array
|
||||
* @total: total number of elements that this should hold
|
||||
* @flags: page allocation flags to use for base array
|
||||
*
|
||||
* Note: all locking must be provided by the caller.
|
||||
*
|
||||
@@ -103,7 +87,8 @@ struct flex_array *flex_array_alloc(int element_size, unsigned int total,
|
||||
gfp_t flags)
|
||||
{
|
||||
struct flex_array *ret;
|
||||
int max_size = nr_base_part_ptrs() * __elements_per_part(element_size);
|
||||
int max_size = FLEX_ARRAY_NR_BASE_PTRS *
|
||||
FLEX_ARRAY_ELEMENTS_PER_PART(element_size);
|
||||
|
||||
/* max_size will end up 0 if element_size > PAGE_SIZE */
|
||||
if (total > max_size)
|
||||
@@ -113,17 +98,21 @@ struct flex_array *flex_array_alloc(int element_size, unsigned int total,
|
||||
return NULL;
|
||||
ret->element_size = element_size;
|
||||
ret->total_nr_elements = total;
|
||||
if (elements_fit_in_base(ret) && !(flags & __GFP_ZERO))
|
||||
memset(ret->parts[0], FLEX_ARRAY_FREE,
|
||||
FLEX_ARRAY_BASE_BYTES_LEFT);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int fa_element_to_part_nr(struct flex_array *fa,
|
||||
unsigned int element_nr)
|
||||
{
|
||||
return element_nr / __elements_per_part(fa->element_size);
|
||||
return element_nr / FLEX_ARRAY_ELEMENTS_PER_PART(fa->element_size);
|
||||
}
|
||||
|
||||
/**
|
||||
* flex_array_free_parts - just free the second-level pages
|
||||
* @fa: the flex array from which to free parts
|
||||
*
|
||||
* This is to be used in cases where the base 'struct flex_array'
|
||||
* has been statically allocated and should not be free.
|
||||
@@ -131,11 +120,10 @@ static int fa_element_to_part_nr(struct flex_array *fa,
|
||||
void flex_array_free_parts(struct flex_array *fa)
|
||||
{
|
||||
int part_nr;
|
||||
int max_part = nr_base_part_ptrs();
|
||||
|
||||
if (elements_fit_in_base(fa))
|
||||
return;
|
||||
for (part_nr = 0; part_nr < max_part; part_nr++)
|
||||
for (part_nr = 0; part_nr < FLEX_ARRAY_NR_BASE_PTRS; part_nr++)
|
||||
kfree(fa->parts[part_nr]);
|
||||
}
|
||||
|
||||
@@ -150,7 +138,8 @@ static unsigned int index_inside_part(struct flex_array *fa,
|
||||
{
|
||||
unsigned int part_offset;
|
||||
|
||||
part_offset = element_nr % __elements_per_part(fa->element_size);
|
||||
part_offset = element_nr %
|
||||
FLEX_ARRAY_ELEMENTS_PER_PART(fa->element_size);
|
||||
return part_offset * fa->element_size;
|
||||
}
|
||||
|
||||
@@ -159,15 +148,12 @@ __fa_get_part(struct flex_array *fa, int part_nr, gfp_t flags)
|
||||
{
|
||||
struct flex_array_part *part = fa->parts[part_nr];
|
||||
if (!part) {
|
||||
/*
|
||||
* This leaves the part pages uninitialized
|
||||
* and with potentially random data, just
|
||||
* as if the user had kmalloc()'d the whole.
|
||||
* __GFP_ZERO can be used to zero it.
|
||||
*/
|
||||
part = kmalloc(FLEX_ARRAY_PART_SIZE, flags);
|
||||
part = kmalloc(sizeof(struct flex_array_part), flags);
|
||||
if (!part)
|
||||
return NULL;
|
||||
if (!(flags & __GFP_ZERO))
|
||||
memset(part, FLEX_ARRAY_FREE,
|
||||
sizeof(struct flex_array_part));
|
||||
fa->parts[part_nr] = part;
|
||||
}
|
||||
return part;
|
||||
@@ -175,9 +161,12 @@ __fa_get_part(struct flex_array *fa, int part_nr, gfp_t flags)
|
||||
|
||||
/**
|
||||
* flex_array_put - copy data into the array at @element_nr
|
||||
* @src: address of data to copy into the array
|
||||
* @fa: the flex array to copy data into
|
||||
* @element_nr: index of the position in which to insert
|
||||
* the new element.
|
||||
* @src: address of data to copy into the array
|
||||
* @flags: page allocation flags to use for array expansion
|
||||
*
|
||||
*
|
||||
* Note that this *copies* the contents of @src into
|
||||
* the array. If you are trying to store an array of
|
||||
@@ -206,10 +195,39 @@ int flex_array_put(struct flex_array *fa, unsigned int element_nr, void *src,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* flex_array_clear - clear element in array at @element_nr
|
||||
* @fa: the flex array of the element.
|
||||
* @element_nr: index of the position to clear.
|
||||
*
|
||||
* Locking must be provided by the caller.
|
||||
*/
|
||||
int flex_array_clear(struct flex_array *fa, unsigned int element_nr)
|
||||
{
|
||||
int part_nr = fa_element_to_part_nr(fa, element_nr);
|
||||
struct flex_array_part *part;
|
||||
void *dst;
|
||||
|
||||
if (element_nr >= fa->total_nr_elements)
|
||||
return -ENOSPC;
|
||||
if (elements_fit_in_base(fa))
|
||||
part = (struct flex_array_part *)&fa->parts[0];
|
||||
else {
|
||||
part = fa->parts[part_nr];
|
||||
if (!part)
|
||||
return -EINVAL;
|
||||
}
|
||||
dst = &part->elements[index_inside_part(fa, element_nr)];
|
||||
memset(dst, FLEX_ARRAY_FREE, fa->element_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* flex_array_prealloc - guarantee that array space exists
|
||||
* @fa: the flex array for which to preallocate parts
|
||||
* @start: index of first array element for which space is allocated
|
||||
* @end: index of last (inclusive) element for which space is allocated
|
||||
* @flags: page allocation flags
|
||||
*
|
||||
* This will guarantee that no future calls to flex_array_put()
|
||||
* will allocate memory. It can be used if you are expecting to
|
||||
@@ -242,6 +260,7 @@ int flex_array_prealloc(struct flex_array *fa, unsigned int start,
|
||||
|
||||
/**
|
||||
* flex_array_get - pull data back out of the array
|
||||
* @fa: the flex array from which to extract data
|
||||
* @element_nr: index of the element to fetch from the array
|
||||
*
|
||||
* Returns a pointer to the data at index @element_nr. Note
|
||||
@@ -266,3 +285,43 @@ void *flex_array_get(struct flex_array *fa, unsigned int element_nr)
|
||||
}
|
||||
return &part->elements[index_inside_part(fa, element_nr)];
|
||||
}
|
||||
|
||||
static int part_is_free(struct flex_array_part *part)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sizeof(struct flex_array_part); i++)
|
||||
if (part->elements[i] != FLEX_ARRAY_FREE)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* flex_array_shrink - free unused second-level pages
|
||||
* @fa: the flex array to shrink
|
||||
*
|
||||
* Frees all second-level pages that consist solely of unused
|
||||
* elements. Returns the number of pages freed.
|
||||
*
|
||||
* Locking must be provided by the caller.
|
||||
*/
|
||||
int flex_array_shrink(struct flex_array *fa)
|
||||
{
|
||||
struct flex_array_part *part;
|
||||
int part_nr;
|
||||
int ret = 0;
|
||||
|
||||
if (elements_fit_in_base(fa))
|
||||
return ret;
|
||||
for (part_nr = 0; part_nr < FLEX_ARRAY_NR_BASE_PTRS; part_nr++) {
|
||||
part = fa->parts[part_nr];
|
||||
if (!part)
|
||||
continue;
|
||||
if (part_is_free(part)) {
|
||||
fa->parts[part_nr] = NULL;
|
||||
kfree(part);
|
||||
ret++;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
@@ -671,7 +671,7 @@ static char *ip4_string(char *p, const u8 *addr, bool leading_zeros)
|
||||
return p;
|
||||
}
|
||||
|
||||
static char *ip6_compressed_string(char *p, const struct in6_addr *addr)
|
||||
static char *ip6_compressed_string(char *p, const char *addr)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
@@ -683,7 +683,12 @@ static char *ip6_compressed_string(char *p, const struct in6_addr *addr)
|
||||
u8 hi;
|
||||
u8 lo;
|
||||
bool needcolon = false;
|
||||
bool useIPv4 = ipv6_addr_v4mapped(addr) || ipv6_addr_is_isatap(addr);
|
||||
bool useIPv4;
|
||||
struct in6_addr in6;
|
||||
|
||||
memcpy(&in6, addr, sizeof(struct in6_addr));
|
||||
|
||||
useIPv4 = ipv6_addr_v4mapped(&in6) || ipv6_addr_is_isatap(&in6);
|
||||
|
||||
memset(zerolength, 0, sizeof(zerolength));
|
||||
|
||||
@@ -695,7 +700,7 @@ static char *ip6_compressed_string(char *p, const struct in6_addr *addr)
|
||||
/* find position of longest 0 run */
|
||||
for (i = 0; i < range; i++) {
|
||||
for (j = i; j < range; j++) {
|
||||
if (addr->s6_addr16[j] != 0)
|
||||
if (in6.s6_addr16[j] != 0)
|
||||
break;
|
||||
zerolength[i]++;
|
||||
}
|
||||
@@ -722,7 +727,7 @@ static char *ip6_compressed_string(char *p, const struct in6_addr *addr)
|
||||
needcolon = false;
|
||||
}
|
||||
/* hex u16 without leading 0s */
|
||||
word = ntohs(addr->s6_addr16[i]);
|
||||
word = ntohs(in6.s6_addr16[i]);
|
||||
hi = word >> 8;
|
||||
lo = word & 0xff;
|
||||
if (hi) {
|
||||
@@ -741,19 +746,19 @@ static char *ip6_compressed_string(char *p, const struct in6_addr *addr)
|
||||
if (useIPv4) {
|
||||
if (needcolon)
|
||||
*p++ = ':';
|
||||
p = ip4_string(p, &addr->s6_addr[12], false);
|
||||
p = ip4_string(p, &in6.s6_addr[12], false);
|
||||
}
|
||||
|
||||
*p = '\0';
|
||||
return p;
|
||||
}
|
||||
|
||||
static char *ip6_string(char *p, const struct in6_addr *addr, const char *fmt)
|
||||
static char *ip6_string(char *p, const char *addr, const char *fmt)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 8; i++) {
|
||||
p = pack_hex_byte(p, addr->s6_addr[2 * i]);
|
||||
p = pack_hex_byte(p, addr->s6_addr[2 * i + 1]);
|
||||
p = pack_hex_byte(p, *addr++);
|
||||
p = pack_hex_byte(p, *addr++);
|
||||
if (fmt[0] == 'I' && i != 7)
|
||||
*p++ = ':';
|
||||
}
|
||||
@@ -768,9 +773,9 @@ static char *ip6_addr_string(char *buf, char *end, const u8 *addr,
|
||||
char ip6_addr[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255")];
|
||||
|
||||
if (fmt[0] == 'I' && fmt[2] == 'c')
|
||||
ip6_compressed_string(ip6_addr, (const struct in6_addr *)addr);
|
||||
ip6_compressed_string(ip6_addr, addr);
|
||||
else
|
||||
ip6_string(ip6_addr, (const struct in6_addr *)addr, fmt);
|
||||
ip6_string(ip6_addr, addr, fmt);
|
||||
|
||||
return string(buf, end, ip6_addr, spec);
|
||||
}
|
||||
@@ -1092,13 +1097,8 @@ int vsnprintf(char *buf, size_t size, const char *fmt, va_list args)
|
||||
|
||||
/* Reject out-of-range values early. Large positive sizes are
|
||||
used for unknown buffer sizes. */
|
||||
if (unlikely((int) size < 0)) {
|
||||
/* There can be only one.. */
|
||||
static char warn = 1;
|
||||
WARN_ON(warn);
|
||||
warn = 0;
|
||||
if (WARN_ON_ONCE((int) size < 0))
|
||||
return 0;
|
||||
}
|
||||
|
||||
str = buf;
|
||||
end = buf + size;
|
||||
@@ -1544,13 +1544,8 @@ int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf)
|
||||
|
||||
struct printf_spec spec = {0};
|
||||
|
||||
if (unlikely((int) size < 0)) {
|
||||
/* There can be only one.. */
|
||||
static char warn = 1;
|
||||
WARN_ON(warn);
|
||||
warn = 0;
|
||||
if (WARN_ON_ONCE((int) size < 0))
|
||||
return 0;
|
||||
}
|
||||
|
||||
str = buf;
|
||||
end = buf + size;
|
||||
|
@@ -135,7 +135,7 @@ static const config configuration_table[10] = {
|
||||
|
||||
/* ===========================================================================
|
||||
* Update a hash value with the given input byte
|
||||
* IN assertion: all calls to to UPDATE_HASH are made with consecutive
|
||||
* IN assertion: all calls to UPDATE_HASH are made with consecutive
|
||||
* input characters, so that a running hash key can be computed from the
|
||||
* previous key instead of complete recalculation each time.
|
||||
*/
|
||||
@@ -146,7 +146,7 @@ static const config configuration_table[10] = {
|
||||
* Insert string str in the dictionary and set match_head to the previous head
|
||||
* of the hash chain (the most recent string with same hash key). Return
|
||||
* the previous length of the hash chain.
|
||||
* IN assertion: all calls to to INSERT_STRING are made with consecutive
|
||||
* IN assertion: all calls to INSERT_STRING are made with consecutive
|
||||
* input characters and the first MIN_MATCH bytes of str are valid
|
||||
* (except for the last MIN_MATCH-1 bytes of the input file).
|
||||
*/
|
||||
|
Reference in New Issue
Block a user