mirror of https://gitee.com/openkylin/linux.git
Merge branch 'for-4.14-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu
Pull percpu fixes from Tejun Heo: "Rather important fixes this time. - The new percpu area allocator had a subtle bug in how it iterates the memory regions and could skip viable areas, which led to allocation failures for module static percpu variables. Dennis fixed the bug and another non-critical one in stat calculation. - Mark noticed that the generic implementations of percpu local atomic reads aren't properly protected against irqs and there's a (slim) chance for split reads on some 32bit systems. Generic implementations are updated to disable irq when read size is larger than ulong size. This may have made some 32bit archs which can do atomic local 64bit accesses generate sub-optimal code. We need to find them out and implement arch-specific overrides" * 'for-4.14-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/tj/percpu: percpu: fix iteration to prevent skipping over block percpu: fix starting offset for chunk statistics traversal percpu: make this_cpu_generic_read() atomic w.r.t. interrupts
This commit is contained in:
commit
ff93026d51
|
@ -115,15 +115,35 @@ do { \
|
|||
(__ret); \
|
||||
})
|
||||
|
||||
#define this_cpu_generic_read(pcp) \
|
||||
#define __this_cpu_generic_read_nopreempt(pcp) \
|
||||
({ \
|
||||
typeof(pcp) __ret; \
|
||||
preempt_disable_notrace(); \
|
||||
__ret = raw_cpu_generic_read(pcp); \
|
||||
__ret = READ_ONCE(*raw_cpu_ptr(&(pcp))); \
|
||||
preempt_enable_notrace(); \
|
||||
__ret; \
|
||||
})
|
||||
|
||||
#define __this_cpu_generic_read_noirq(pcp) \
|
||||
({ \
|
||||
typeof(pcp) __ret; \
|
||||
unsigned long __flags; \
|
||||
raw_local_irq_save(__flags); \
|
||||
__ret = raw_cpu_generic_read(pcp); \
|
||||
raw_local_irq_restore(__flags); \
|
||||
__ret; \
|
||||
})
|
||||
|
||||
#define this_cpu_generic_read(pcp) \
|
||||
({ \
|
||||
typeof(pcp) __ret; \
|
||||
if (__native_word(pcp)) \
|
||||
__ret = __this_cpu_generic_read_nopreempt(pcp); \
|
||||
else \
|
||||
__ret = __this_cpu_generic_read_noirq(pcp); \
|
||||
__ret; \
|
||||
})
|
||||
|
||||
#define this_cpu_generic_to_op(pcp, val, op) \
|
||||
do { \
|
||||
unsigned long __flags; \
|
||||
|
|
|
@ -73,7 +73,7 @@ static void chunk_map_stats(struct seq_file *m, struct pcpu_chunk *chunk,
|
|||
last_alloc + 1 : 0;
|
||||
|
||||
as_len = 0;
|
||||
start = chunk->start_offset;
|
||||
start = chunk->start_offset / PCPU_MIN_ALLOC_SIZE;
|
||||
|
||||
/*
|
||||
* If a bit is set in the allocation map, the bound_map identifies
|
||||
|
|
|
@ -353,6 +353,8 @@ static void pcpu_next_md_free_region(struct pcpu_chunk *chunk, int *bit_off,
|
|||
block->contig_hint_start);
|
||||
return;
|
||||
}
|
||||
/* reset to satisfy the second predicate above */
|
||||
block_off = 0;
|
||||
|
||||
*bits = block->right_free;
|
||||
*bit_off = (i + 1) * PCPU_BITMAP_BLOCK_BITS - block->right_free;
|
||||
|
@ -407,6 +409,8 @@ static void pcpu_next_fit_region(struct pcpu_chunk *chunk, int alloc_bits,
|
|||
*bit_off = pcpu_block_off_to_off(i, block->first_free);
|
||||
return;
|
||||
}
|
||||
/* reset to satisfy the second predicate above */
|
||||
block_off = 0;
|
||||
|
||||
*bit_off = ALIGN(PCPU_BITMAP_BLOCK_BITS - block->right_free,
|
||||
align);
|
||||
|
|
Loading…
Reference in New Issue