Merge branch 'akpm' (patches from Andrew)
Merge misc fixes from Andrew Morton: "A lot of stuff, sorry about that. A week on a beach, then a bunch of time catching up then more time letting it bake in -next. Shan't do that again!" * emailed patches from Andrew Morton <akpm@linux-foundation.org>: (51 commits) include/linux/fs.h: fix comment about struct address_space checkpatch: fix ignoring cover-letter logic m32r: fix build failure lib/ratelimit.c: use deferred printk() version kernel/params.c: improve STANDARD_PARAM_DEF readability kernel/params.c: fix an overflow in param_attr_show kernel/params.c: fix the maximum length in param_get_string mm/memory_hotplug: define find_{smallest|biggest}_section_pfn as unsigned long mm/memory_hotplug: change pfn_to_section_nr/section_nr_to_pfn macro to inline function kernel/kcmp.c: drop branch leftover typo memremap: add scheduling point to devm_memremap_pages mm, page_alloc: add scheduling point to memmap_init_zone mm, memory_hotplug: add scheduling point to __add_pages lib/idr.c: fix comment for idr_replace() mm: memcontrol: use vmalloc fallback for large kmem memcg arrays kernel/sysctl.c: remove duplicate UINT_MAX check on do_proc_douintvec_conv() include/linux/bitfield.h: remove 32bit from FIELD_GET comment block lib/lz4: make arrays static const, reduces object code size exec: binfmt_misc: kill the onstack iname[BINPRM_BUF_SIZE] array exec: binfmt_misc: fix race between load_misc_binary() and kill_node() ...
This commit is contained in:
commit
b7e1416441
|
@ -8,6 +8,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <linux/mm_types.h>
|
#include <linux/mm_types.h>
|
||||||
|
#include <linux/sched.h>
|
||||||
|
|
||||||
#include <asm/machvec.h>
|
#include <asm/machvec.h>
|
||||||
#include <asm/compiler.h>
|
#include <asm/compiler.h>
|
||||||
|
|
|
@ -194,6 +194,10 @@ config TIMER_DIVIDE
|
||||||
int "Timer divider (integer)"
|
int "Timer divider (integer)"
|
||||||
default "128"
|
default "128"
|
||||||
|
|
||||||
|
config CPU_BIG_ENDIAN
|
||||||
|
bool "Generate big endian code"
|
||||||
|
default n
|
||||||
|
|
||||||
config CPU_LITTLE_ENDIAN
|
config CPU_LITTLE_ENDIAN
|
||||||
bool "Generate little endian code"
|
bool "Generate little endian code"
|
||||||
default n
|
default n
|
||||||
|
|
|
@ -114,6 +114,15 @@ static void set_eit_vector_entries(void)
|
||||||
_flush_cache_copyback_all();
|
_flush_cache_copyback_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void abort(void)
|
||||||
|
{
|
||||||
|
BUG();
|
||||||
|
|
||||||
|
/* if that doesn't kill us, halt */
|
||||||
|
panic("Oops failed to kill thread");
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(abort);
|
||||||
|
|
||||||
void __init trap_init(void)
|
void __init trap_init(void)
|
||||||
{
|
{
|
||||||
set_eit_vector_entries();
|
set_eit_vector_entries();
|
||||||
|
|
|
@ -71,6 +71,8 @@
|
||||||
#define RIWAR_WRTYP_ALLOC 0x00006000
|
#define RIWAR_WRTYP_ALLOC 0x00006000
|
||||||
#define RIWAR_SIZE_MASK 0x0000003F
|
#define RIWAR_SIZE_MASK 0x0000003F
|
||||||
|
|
||||||
|
static DEFINE_SPINLOCK(fsl_rio_config_lock);
|
||||||
|
|
||||||
#define __fsl_read_rio_config(x, addr, err, op) \
|
#define __fsl_read_rio_config(x, addr, err, op) \
|
||||||
__asm__ __volatile__( \
|
__asm__ __volatile__( \
|
||||||
"1: "op" %1,0(%2)\n" \
|
"1: "op" %1,0(%2)\n" \
|
||||||
|
@ -184,6 +186,7 @@ fsl_rio_config_read(struct rio_mport *mport, int index, u16 destid,
|
||||||
u8 hopcount, u32 offset, int len, u32 *val)
|
u8 hopcount, u32 offset, int len, u32 *val)
|
||||||
{
|
{
|
||||||
struct rio_priv *priv = mport->priv;
|
struct rio_priv *priv = mport->priv;
|
||||||
|
unsigned long flags;
|
||||||
u8 *data;
|
u8 *data;
|
||||||
u32 rval, err = 0;
|
u32 rval, err = 0;
|
||||||
|
|
||||||
|
@ -197,6 +200,8 @@ fsl_rio_config_read(struct rio_mport *mport, int index, u16 destid,
|
||||||
if (offset > (0x1000000 - len) || !IS_ALIGNED(offset, len))
|
if (offset > (0x1000000 - len) || !IS_ALIGNED(offset, len))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&fsl_rio_config_lock, flags);
|
||||||
|
|
||||||
out_be32(&priv->maint_atmu_regs->rowtar,
|
out_be32(&priv->maint_atmu_regs->rowtar,
|
||||||
(destid << 22) | (hopcount << 12) | (offset >> 12));
|
(destid << 22) | (hopcount << 12) | (offset >> 12));
|
||||||
out_be32(&priv->maint_atmu_regs->rowtear, (destid >> 10));
|
out_be32(&priv->maint_atmu_regs->rowtear, (destid >> 10));
|
||||||
|
@ -213,6 +218,7 @@ fsl_rio_config_read(struct rio_mport *mport, int index, u16 destid,
|
||||||
__fsl_read_rio_config(rval, data, err, "lwz");
|
__fsl_read_rio_config(rval, data, err, "lwz");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
spin_unlock_irqrestore(&fsl_rio_config_lock, flags);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,6 +227,7 @@ fsl_rio_config_read(struct rio_mport *mport, int index, u16 destid,
|
||||||
err, destid, hopcount, offset);
|
err, destid, hopcount, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&fsl_rio_config_lock, flags);
|
||||||
*val = rval;
|
*val = rval;
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
|
@ -244,7 +251,10 @@ fsl_rio_config_write(struct rio_mport *mport, int index, u16 destid,
|
||||||
u8 hopcount, u32 offset, int len, u32 val)
|
u8 hopcount, u32 offset, int len, u32 val)
|
||||||
{
|
{
|
||||||
struct rio_priv *priv = mport->priv;
|
struct rio_priv *priv = mport->priv;
|
||||||
|
unsigned long flags;
|
||||||
u8 *data;
|
u8 *data;
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
pr_debug
|
pr_debug
|
||||||
("fsl_rio_config_write:"
|
("fsl_rio_config_write:"
|
||||||
" index %d destid %d hopcount %d offset %8.8x len %d val %8.8x\n",
|
" index %d destid %d hopcount %d offset %8.8x len %d val %8.8x\n",
|
||||||
|
@ -255,6 +265,8 @@ fsl_rio_config_write(struct rio_mport *mport, int index, u16 destid,
|
||||||
if (offset > (0x1000000 - len) || !IS_ALIGNED(offset, len))
|
if (offset > (0x1000000 - len) || !IS_ALIGNED(offset, len))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&fsl_rio_config_lock, flags);
|
||||||
|
|
||||||
out_be32(&priv->maint_atmu_regs->rowtar,
|
out_be32(&priv->maint_atmu_regs->rowtar,
|
||||||
(destid << 22) | (hopcount << 12) | (offset >> 12));
|
(destid << 22) | (hopcount << 12) | (offset >> 12));
|
||||||
out_be32(&priv->maint_atmu_regs->rowtear, (destid >> 10));
|
out_be32(&priv->maint_atmu_regs->rowtear, (destid >> 10));
|
||||||
|
@ -271,10 +283,11 @@ fsl_rio_config_write(struct rio_mport *mport, int index, u16 destid,
|
||||||
out_be32((u32 *) data, val);
|
out_be32((u32 *) data, val);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
ret = -EINVAL;
|
||||||
}
|
}
|
||||||
|
spin_unlock_irqrestore(&fsl_rio_config_lock, flags);
|
||||||
|
|
||||||
return 0;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void fsl_rio_inbound_mem_init(struct rio_priv *priv)
|
static void fsl_rio_inbound_mem_init(struct rio_priv *priv)
|
||||||
|
|
|
@ -104,6 +104,8 @@
|
||||||
|
|
||||||
#define DOORBELL_MESSAGE_SIZE 0x08
|
#define DOORBELL_MESSAGE_SIZE 0x08
|
||||||
|
|
||||||
|
static DEFINE_SPINLOCK(fsl_rio_doorbell_lock);
|
||||||
|
|
||||||
struct rio_msg_regs {
|
struct rio_msg_regs {
|
||||||
u32 omr;
|
u32 omr;
|
||||||
u32 osr;
|
u32 osr;
|
||||||
|
@ -626,9 +628,13 @@ err_out:
|
||||||
int fsl_rio_doorbell_send(struct rio_mport *mport,
|
int fsl_rio_doorbell_send(struct rio_mport *mport,
|
||||||
int index, u16 destid, u16 data)
|
int index, u16 destid, u16 data)
|
||||||
{
|
{
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
pr_debug("fsl_doorbell_send: index %d destid %4.4x data %4.4x\n",
|
pr_debug("fsl_doorbell_send: index %d destid %4.4x data %4.4x\n",
|
||||||
index, destid, data);
|
index, destid, data);
|
||||||
|
|
||||||
|
spin_lock_irqsave(&fsl_rio_doorbell_lock, flags);
|
||||||
|
|
||||||
/* In the serial version silicons, such as MPC8548, MPC8641,
|
/* In the serial version silicons, such as MPC8548, MPC8641,
|
||||||
* below operations is must be.
|
* below operations is must be.
|
||||||
*/
|
*/
|
||||||
|
@ -638,6 +644,8 @@ int fsl_rio_doorbell_send(struct rio_mport *mport,
|
||||||
out_be32(&dbell->dbell_regs->oddatr, (index << 20) | data);
|
out_be32(&dbell->dbell_regs->oddatr, (index << 20) | data);
|
||||||
out_be32(&dbell->dbell_regs->odmr, 0x00000001);
|
out_be32(&dbell->dbell_regs->odmr, 0x00000001);
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&fsl_rio_doorbell_lock, flags);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,9 +43,7 @@ enum {
|
||||||
GPIO_PG7, GPIO_PG6, GPIO_PG5, GPIO_PG4,
|
GPIO_PG7, GPIO_PG6, GPIO_PG5, GPIO_PG4,
|
||||||
GPIO_PG3, GPIO_PG2, GPIO_PG1, GPIO_PG0,
|
GPIO_PG3, GPIO_PG2, GPIO_PG1, GPIO_PG0,
|
||||||
|
|
||||||
/* Port H */
|
/* Port H - Port H does not have a Data Register */
|
||||||
GPIO_PH7, GPIO_PH6, GPIO_PH5, GPIO_PH4,
|
|
||||||
GPIO_PH3, GPIO_PH2, GPIO_PH1, GPIO_PH0,
|
|
||||||
|
|
||||||
/* Port I - not on device */
|
/* Port I - not on device */
|
||||||
|
|
||||||
|
|
|
@ -45,9 +45,7 @@ enum {
|
||||||
GPIO_PG7, GPIO_PG6, GPIO_PG5, GPIO_PG4,
|
GPIO_PG7, GPIO_PG6, GPIO_PG5, GPIO_PG4,
|
||||||
GPIO_PG3, GPIO_PG2, GPIO_PG1, GPIO_PG0,
|
GPIO_PG3, GPIO_PG2, GPIO_PG1, GPIO_PG0,
|
||||||
|
|
||||||
/* Port H */
|
/* Port H - Port H does not have a Data Register */
|
||||||
GPIO_PH7, GPIO_PH6, GPIO_PH5, GPIO_PH4,
|
|
||||||
GPIO_PH3, GPIO_PH2, GPIO_PH1, GPIO_PH0,
|
|
||||||
|
|
||||||
/* Port I - not on device */
|
/* Port I - not on device */
|
||||||
|
|
||||||
|
|
|
@ -67,7 +67,7 @@ enum {
|
||||||
GPIO_PTN3, GPIO_PTN2, GPIO_PTN1, GPIO_PTN0,
|
GPIO_PTN3, GPIO_PTN2, GPIO_PTN1, GPIO_PTN0,
|
||||||
|
|
||||||
/* PTQ */
|
/* PTQ */
|
||||||
GPIO_PTQ7, GPIO_PTQ6, GPIO_PTQ5, GPIO_PTQ4,
|
GPIO_PTQ6, GPIO_PTQ5, GPIO_PTQ4,
|
||||||
GPIO_PTQ3, GPIO_PTQ2, GPIO_PTQ1, GPIO_PTQ0,
|
GPIO_PTQ3, GPIO_PTQ2, GPIO_PTQ1, GPIO_PTQ0,
|
||||||
|
|
||||||
/* PTR */
|
/* PTR */
|
||||||
|
|
|
@ -40,7 +40,7 @@ enum {
|
||||||
|
|
||||||
/* PTJ */
|
/* PTJ */
|
||||||
GPIO_PTJ0, GPIO_PTJ1, GPIO_PTJ2, GPIO_PTJ3,
|
GPIO_PTJ0, GPIO_PTJ1, GPIO_PTJ2, GPIO_PTJ3,
|
||||||
GPIO_PTJ4, GPIO_PTJ5, GPIO_PTJ6, GPIO_PTJ7_RESV,
|
GPIO_PTJ4, GPIO_PTJ5, GPIO_PTJ6,
|
||||||
|
|
||||||
/* PTK */
|
/* PTK */
|
||||||
GPIO_PTK0, GPIO_PTK1, GPIO_PTK2, GPIO_PTK3,
|
GPIO_PTK0, GPIO_PTK1, GPIO_PTK2, GPIO_PTK3,
|
||||||
|
@ -48,7 +48,7 @@ enum {
|
||||||
|
|
||||||
/* PTL */
|
/* PTL */
|
||||||
GPIO_PTL0, GPIO_PTL1, GPIO_PTL2, GPIO_PTL3,
|
GPIO_PTL0, GPIO_PTL1, GPIO_PTL2, GPIO_PTL3,
|
||||||
GPIO_PTL4, GPIO_PTL5, GPIO_PTL6, GPIO_PTL7_RESV,
|
GPIO_PTL4, GPIO_PTL5, GPIO_PTL6,
|
||||||
|
|
||||||
/* PTM */
|
/* PTM */
|
||||||
GPIO_PTM0, GPIO_PTM1, GPIO_PTM2, GPIO_PTM3,
|
GPIO_PTM0, GPIO_PTM1, GPIO_PTM2, GPIO_PTM3,
|
||||||
|
@ -56,7 +56,7 @@ enum {
|
||||||
|
|
||||||
/* PTN */
|
/* PTN */
|
||||||
GPIO_PTN0, GPIO_PTN1, GPIO_PTN2, GPIO_PTN3,
|
GPIO_PTN0, GPIO_PTN1, GPIO_PTN2, GPIO_PTN3,
|
||||||
GPIO_PTN4, GPIO_PTN5, GPIO_PTN6, GPIO_PTN7_RESV,
|
GPIO_PTN4, GPIO_PTN5, GPIO_PTN6,
|
||||||
|
|
||||||
/* PTO */
|
/* PTO */
|
||||||
GPIO_PTO0, GPIO_PTO1, GPIO_PTO2, GPIO_PTO3,
|
GPIO_PTO0, GPIO_PTO1, GPIO_PTO2, GPIO_PTO3,
|
||||||
|
@ -68,7 +68,7 @@ enum {
|
||||||
|
|
||||||
/* PTQ */
|
/* PTQ */
|
||||||
GPIO_PTQ0, GPIO_PTQ1, GPIO_PTQ2, GPIO_PTQ3,
|
GPIO_PTQ0, GPIO_PTQ1, GPIO_PTQ2, GPIO_PTQ3,
|
||||||
GPIO_PTQ4, GPIO_PTQ5, GPIO_PTQ6, GPIO_PTQ7_RESV,
|
GPIO_PTQ4, GPIO_PTQ5, GPIO_PTQ6,
|
||||||
|
|
||||||
/* PTR */
|
/* PTR */
|
||||||
GPIO_PTR0, GPIO_PTR1, GPIO_PTR2, GPIO_PTR3,
|
GPIO_PTR0, GPIO_PTR1, GPIO_PTR2, GPIO_PTR3,
|
||||||
|
|
|
@ -913,6 +913,7 @@ enum lru_status binder_alloc_free_page(struct list_head *item,
|
||||||
struct binder_alloc *alloc;
|
struct binder_alloc *alloc;
|
||||||
uintptr_t page_addr;
|
uintptr_t page_addr;
|
||||||
size_t index;
|
size_t index;
|
||||||
|
struct vm_area_struct *vma;
|
||||||
|
|
||||||
alloc = page->alloc;
|
alloc = page->alloc;
|
||||||
if (!mutex_trylock(&alloc->mutex))
|
if (!mutex_trylock(&alloc->mutex))
|
||||||
|
@ -923,16 +924,22 @@ enum lru_status binder_alloc_free_page(struct list_head *item,
|
||||||
|
|
||||||
index = page - alloc->pages;
|
index = page - alloc->pages;
|
||||||
page_addr = (uintptr_t)alloc->buffer + index * PAGE_SIZE;
|
page_addr = (uintptr_t)alloc->buffer + index * PAGE_SIZE;
|
||||||
if (alloc->vma) {
|
vma = alloc->vma;
|
||||||
|
if (vma) {
|
||||||
mm = get_task_mm(alloc->tsk);
|
mm = get_task_mm(alloc->tsk);
|
||||||
if (!mm)
|
if (!mm)
|
||||||
goto err_get_task_mm_failed;
|
goto err_get_task_mm_failed;
|
||||||
if (!down_write_trylock(&mm->mmap_sem))
|
if (!down_write_trylock(&mm->mmap_sem))
|
||||||
goto err_down_write_mmap_sem_failed;
|
goto err_down_write_mmap_sem_failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
list_lru_isolate(lru, item);
|
||||||
|
spin_unlock(lock);
|
||||||
|
|
||||||
|
if (vma) {
|
||||||
trace_binder_unmap_user_start(alloc, index);
|
trace_binder_unmap_user_start(alloc, index);
|
||||||
|
|
||||||
zap_page_range(alloc->vma,
|
zap_page_range(vma,
|
||||||
page_addr + alloc->user_buffer_offset,
|
page_addr + alloc->user_buffer_offset,
|
||||||
PAGE_SIZE);
|
PAGE_SIZE);
|
||||||
|
|
||||||
|
@ -950,13 +957,12 @@ enum lru_status binder_alloc_free_page(struct list_head *item,
|
||||||
|
|
||||||
trace_binder_unmap_kernel_end(alloc, index);
|
trace_binder_unmap_kernel_end(alloc, index);
|
||||||
|
|
||||||
list_lru_isolate(lru, item);
|
spin_lock(lock);
|
||||||
|
|
||||||
mutex_unlock(&alloc->mutex);
|
mutex_unlock(&alloc->mutex);
|
||||||
return LRU_REMOVED;
|
return LRU_REMOVED_RETRY;
|
||||||
|
|
||||||
err_down_write_mmap_sem_failed:
|
err_down_write_mmap_sem_failed:
|
||||||
mmput(mm);
|
mmput_async(mm);
|
||||||
err_get_task_mm_failed:
|
err_get_task_mm_failed:
|
||||||
err_page_already_freed:
|
err_page_already_freed:
|
||||||
mutex_unlock(&alloc->mutex);
|
mutex_unlock(&alloc->mutex);
|
||||||
|
|
|
@ -766,27 +766,6 @@ static void zram_slot_unlock(struct zram *zram, u32 index)
|
||||||
bit_spin_unlock(ZRAM_ACCESS, &zram->table[index].value);
|
bit_spin_unlock(ZRAM_ACCESS, &zram->table[index].value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool zram_same_page_read(struct zram *zram, u32 index,
|
|
||||||
struct page *page,
|
|
||||||
unsigned int offset, unsigned int len)
|
|
||||||
{
|
|
||||||
zram_slot_lock(zram, index);
|
|
||||||
if (unlikely(!zram_get_handle(zram, index) ||
|
|
||||||
zram_test_flag(zram, index, ZRAM_SAME))) {
|
|
||||||
void *mem;
|
|
||||||
|
|
||||||
zram_slot_unlock(zram, index);
|
|
||||||
mem = kmap_atomic(page);
|
|
||||||
zram_fill_page(mem + offset, len,
|
|
||||||
zram_get_element(zram, index));
|
|
||||||
kunmap_atomic(mem);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
zram_slot_unlock(zram, index);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void zram_meta_free(struct zram *zram, u64 disksize)
|
static void zram_meta_free(struct zram *zram, u64 disksize)
|
||||||
{
|
{
|
||||||
size_t num_pages = disksize >> PAGE_SHIFT;
|
size_t num_pages = disksize >> PAGE_SHIFT;
|
||||||
|
@ -884,11 +863,20 @@ static int __zram_bvec_read(struct zram *zram, struct page *page, u32 index,
|
||||||
zram_slot_unlock(zram, index);
|
zram_slot_unlock(zram, index);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zram_same_page_read(zram, index, page, 0, PAGE_SIZE))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
zram_slot_lock(zram, index);
|
zram_slot_lock(zram, index);
|
||||||
handle = zram_get_handle(zram, index);
|
handle = zram_get_handle(zram, index);
|
||||||
|
if (!handle || zram_test_flag(zram, index, ZRAM_SAME)) {
|
||||||
|
unsigned long value;
|
||||||
|
void *mem;
|
||||||
|
|
||||||
|
value = handle ? zram_get_element(zram, index) : 0;
|
||||||
|
mem = kmap_atomic(page);
|
||||||
|
zram_fill_page(mem, PAGE_SIZE, value);
|
||||||
|
kunmap_atomic(mem);
|
||||||
|
zram_slot_unlock(zram, index);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
size = zram_get_obj_size(zram, index);
|
size = zram_get_obj_size(zram, index);
|
||||||
|
|
||||||
src = zs_map_object(zram->mem_pool, handle, ZS_MM_RO);
|
src = zs_map_object(zram->mem_pool, handle, ZS_MM_RO);
|
||||||
|
|
|
@ -51,6 +51,8 @@ module_param(mbox_sel, byte, S_IRUGO);
|
||||||
MODULE_PARM_DESC(mbox_sel,
|
MODULE_PARM_DESC(mbox_sel,
|
||||||
"RIO Messaging MBOX Selection Mask (default: 0x0f = all)");
|
"RIO Messaging MBOX Selection Mask (default: 0x0f = all)");
|
||||||
|
|
||||||
|
static DEFINE_SPINLOCK(tsi721_maint_lock);
|
||||||
|
|
||||||
static void tsi721_omsg_handler(struct tsi721_device *priv, int ch);
|
static void tsi721_omsg_handler(struct tsi721_device *priv, int ch);
|
||||||
static void tsi721_imsg_handler(struct tsi721_device *priv, int ch);
|
static void tsi721_imsg_handler(struct tsi721_device *priv, int ch);
|
||||||
|
|
||||||
|
@ -124,12 +126,15 @@ static int tsi721_maint_dma(struct tsi721_device *priv, u32 sys_size,
|
||||||
void __iomem *regs = priv->regs + TSI721_DMAC_BASE(priv->mdma.ch_id);
|
void __iomem *regs = priv->regs + TSI721_DMAC_BASE(priv->mdma.ch_id);
|
||||||
struct tsi721_dma_desc *bd_ptr;
|
struct tsi721_dma_desc *bd_ptr;
|
||||||
u32 rd_count, swr_ptr, ch_stat;
|
u32 rd_count, swr_ptr, ch_stat;
|
||||||
|
unsigned long flags;
|
||||||
int i, err = 0;
|
int i, err = 0;
|
||||||
u32 op = do_wr ? MAINT_WR : MAINT_RD;
|
u32 op = do_wr ? MAINT_WR : MAINT_RD;
|
||||||
|
|
||||||
if (offset > (RIO_MAINT_SPACE_SZ - len) || (len != sizeof(u32)))
|
if (offset > (RIO_MAINT_SPACE_SZ - len) || (len != sizeof(u32)))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
spin_lock_irqsave(&tsi721_maint_lock, flags);
|
||||||
|
|
||||||
bd_ptr = priv->mdma.bd_base;
|
bd_ptr = priv->mdma.bd_base;
|
||||||
|
|
||||||
rd_count = ioread32(regs + TSI721_DMAC_DRDCNT);
|
rd_count = ioread32(regs + TSI721_DMAC_DRDCNT);
|
||||||
|
@ -197,7 +202,9 @@ static int tsi721_maint_dma(struct tsi721_device *priv, u32 sys_size,
|
||||||
*/
|
*/
|
||||||
swr_ptr = ioread32(regs + TSI721_DMAC_DSWP);
|
swr_ptr = ioread32(regs + TSI721_DMAC_DSWP);
|
||||||
iowrite32(swr_ptr, regs + TSI721_DMAC_DSRP);
|
iowrite32(swr_ptr, regs + TSI721_DMAC_DSRP);
|
||||||
|
|
||||||
err_out:
|
err_out:
|
||||||
|
spin_unlock_irqrestore(&tsi721_maint_lock, flags);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,17 +13,9 @@
|
||||||
#include <linux/rio.h>
|
#include <linux/rio.h>
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
|
||||||
/*
|
|
||||||
* These interrupt-safe spinlocks protect all accesses to RIO
|
|
||||||
* configuration space and doorbell access.
|
|
||||||
*/
|
|
||||||
static DEFINE_SPINLOCK(rio_config_lock);
|
|
||||||
static DEFINE_SPINLOCK(rio_doorbell_lock);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Wrappers for all RIO configuration access functions. They just check
|
* Wrappers for all RIO configuration access functions. They just check
|
||||||
* alignment, do locking and call the low-level functions pointed to
|
* alignment and call the low-level functions pointed to by rio_mport->ops.
|
||||||
* by rio_mport->ops.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define RIO_8_BAD 0
|
#define RIO_8_BAD 0
|
||||||
|
@ -44,13 +36,10 @@ int __rio_local_read_config_##size \
|
||||||
(struct rio_mport *mport, u32 offset, type *value) \
|
(struct rio_mport *mport, u32 offset, type *value) \
|
||||||
{ \
|
{ \
|
||||||
int res; \
|
int res; \
|
||||||
unsigned long flags; \
|
|
||||||
u32 data = 0; \
|
u32 data = 0; \
|
||||||
if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
|
if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
|
||||||
spin_lock_irqsave(&rio_config_lock, flags); \
|
|
||||||
res = mport->ops->lcread(mport, mport->id, offset, len, &data); \
|
res = mport->ops->lcread(mport, mport->id, offset, len, &data); \
|
||||||
*value = (type)data; \
|
*value = (type)data; \
|
||||||
spin_unlock_irqrestore(&rio_config_lock, flags); \
|
|
||||||
return res; \
|
return res; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,13 +56,8 @@ int __rio_local_read_config_##size \
|
||||||
int __rio_local_write_config_##size \
|
int __rio_local_write_config_##size \
|
||||||
(struct rio_mport *mport, u32 offset, type value) \
|
(struct rio_mport *mport, u32 offset, type value) \
|
||||||
{ \
|
{ \
|
||||||
int res; \
|
|
||||||
unsigned long flags; \
|
|
||||||
if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
|
if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
|
||||||
spin_lock_irqsave(&rio_config_lock, flags); \
|
return mport->ops->lcwrite(mport, mport->id, offset, len, value);\
|
||||||
res = mport->ops->lcwrite(mport, mport->id, offset, len, value);\
|
|
||||||
spin_unlock_irqrestore(&rio_config_lock, flags); \
|
|
||||||
return res; \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RIO_LOP_READ(8, u8, 1)
|
RIO_LOP_READ(8, u8, 1)
|
||||||
|
@ -104,13 +88,10 @@ int rio_mport_read_config_##size \
|
||||||
(struct rio_mport *mport, u16 destid, u8 hopcount, u32 offset, type *value) \
|
(struct rio_mport *mport, u16 destid, u8 hopcount, u32 offset, type *value) \
|
||||||
{ \
|
{ \
|
||||||
int res; \
|
int res; \
|
||||||
unsigned long flags; \
|
|
||||||
u32 data = 0; \
|
u32 data = 0; \
|
||||||
if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
|
if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
|
||||||
spin_lock_irqsave(&rio_config_lock, flags); \
|
|
||||||
res = mport->ops->cread(mport, mport->id, destid, hopcount, offset, len, &data); \
|
res = mport->ops->cread(mport, mport->id, destid, hopcount, offset, len, &data); \
|
||||||
*value = (type)data; \
|
*value = (type)data; \
|
||||||
spin_unlock_irqrestore(&rio_config_lock, flags); \
|
|
||||||
return res; \
|
return res; \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,13 +108,9 @@ int rio_mport_read_config_##size \
|
||||||
int rio_mport_write_config_##size \
|
int rio_mport_write_config_##size \
|
||||||
(struct rio_mport *mport, u16 destid, u8 hopcount, u32 offset, type value) \
|
(struct rio_mport *mport, u16 destid, u8 hopcount, u32 offset, type value) \
|
||||||
{ \
|
{ \
|
||||||
int res; \
|
|
||||||
unsigned long flags; \
|
|
||||||
if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
|
if (RIO_##size##_BAD) return RIO_BAD_SIZE; \
|
||||||
spin_lock_irqsave(&rio_config_lock, flags); \
|
return mport->ops->cwrite(mport, mport->id, destid, hopcount, \
|
||||||
res = mport->ops->cwrite(mport, mport->id, destid, hopcount, offset, len, value); \
|
offset, len, value); \
|
||||||
spin_unlock_irqrestore(&rio_config_lock, flags); \
|
|
||||||
return res; \
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RIO_OP_READ(8, u8, 1)
|
RIO_OP_READ(8, u8, 1)
|
||||||
|
@ -162,14 +139,7 @@ EXPORT_SYMBOL_GPL(rio_mport_write_config_32);
|
||||||
*/
|
*/
|
||||||
int rio_mport_send_doorbell(struct rio_mport *mport, u16 destid, u16 data)
|
int rio_mport_send_doorbell(struct rio_mport *mport, u16 destid, u16 data)
|
||||||
{
|
{
|
||||||
int res;
|
return mport->ops->dsend(mport, mport->id, destid, data);
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&rio_doorbell_lock, flags);
|
|
||||||
res = mport->ops->dsend(mport, mport->id, destid, data);
|
|
||||||
spin_unlock_irqrestore(&rio_doorbell_lock, flags);
|
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_SYMBOL_GPL(rio_mport_send_doorbell);
|
EXPORT_SYMBOL_GPL(rio_mport_send_doorbell);
|
||||||
|
|
|
@ -54,7 +54,7 @@ typedef struct {
|
||||||
int size; /* size of magic/mask */
|
int size; /* size of magic/mask */
|
||||||
char *magic; /* magic or filename extension */
|
char *magic; /* magic or filename extension */
|
||||||
char *mask; /* mask, NULL for exact match */
|
char *mask; /* mask, NULL for exact match */
|
||||||
char *interpreter; /* filename of interpreter */
|
const char *interpreter; /* filename of interpreter */
|
||||||
char *name;
|
char *name;
|
||||||
struct dentry *dentry;
|
struct dentry *dentry;
|
||||||
struct file *interp_file;
|
struct file *interp_file;
|
||||||
|
@ -131,27 +131,26 @@ static int load_misc_binary(struct linux_binprm *bprm)
|
||||||
{
|
{
|
||||||
Node *fmt;
|
Node *fmt;
|
||||||
struct file *interp_file = NULL;
|
struct file *interp_file = NULL;
|
||||||
char iname[BINPRM_BUF_SIZE];
|
|
||||||
const char *iname_addr = iname;
|
|
||||||
int retval;
|
int retval;
|
||||||
int fd_binary = -1;
|
int fd_binary = -1;
|
||||||
|
|
||||||
retval = -ENOEXEC;
|
retval = -ENOEXEC;
|
||||||
if (!enabled)
|
if (!enabled)
|
||||||
goto ret;
|
return retval;
|
||||||
|
|
||||||
/* to keep locking time low, we copy the interpreter string */
|
/* to keep locking time low, we copy the interpreter string */
|
||||||
read_lock(&entries_lock);
|
read_lock(&entries_lock);
|
||||||
fmt = check_file(bprm);
|
fmt = check_file(bprm);
|
||||||
if (fmt)
|
if (fmt)
|
||||||
strlcpy(iname, fmt->interpreter, BINPRM_BUF_SIZE);
|
dget(fmt->dentry);
|
||||||
read_unlock(&entries_lock);
|
read_unlock(&entries_lock);
|
||||||
if (!fmt)
|
if (!fmt)
|
||||||
goto ret;
|
return retval;
|
||||||
|
|
||||||
/* Need to be able to load the file after exec */
|
/* Need to be able to load the file after exec */
|
||||||
|
retval = -ENOENT;
|
||||||
if (bprm->interp_flags & BINPRM_FLAGS_PATH_INACCESSIBLE)
|
if (bprm->interp_flags & BINPRM_FLAGS_PATH_INACCESSIBLE)
|
||||||
return -ENOENT;
|
goto ret;
|
||||||
|
|
||||||
if (!(fmt->flags & MISC_FMT_PRESERVE_ARGV0)) {
|
if (!(fmt->flags & MISC_FMT_PRESERVE_ARGV0)) {
|
||||||
retval = remove_arg_zero(bprm);
|
retval = remove_arg_zero(bprm);
|
||||||
|
@ -195,22 +194,22 @@ static int load_misc_binary(struct linux_binprm *bprm)
|
||||||
bprm->argc++;
|
bprm->argc++;
|
||||||
|
|
||||||
/* add the interp as argv[0] */
|
/* add the interp as argv[0] */
|
||||||
retval = copy_strings_kernel(1, &iname_addr, bprm);
|
retval = copy_strings_kernel(1, &fmt->interpreter, bprm);
|
||||||
if (retval < 0)
|
if (retval < 0)
|
||||||
goto error;
|
goto error;
|
||||||
bprm->argc++;
|
bprm->argc++;
|
||||||
|
|
||||||
/* Update interp in case binfmt_script needs it. */
|
/* Update interp in case binfmt_script needs it. */
|
||||||
retval = bprm_change_interp(iname, bprm);
|
retval = bprm_change_interp(fmt->interpreter, bprm);
|
||||||
if (retval < 0)
|
if (retval < 0)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (fmt->flags & MISC_FMT_OPEN_FILE && fmt->interp_file) {
|
if (fmt->flags & MISC_FMT_OPEN_FILE) {
|
||||||
interp_file = filp_clone_open(fmt->interp_file);
|
interp_file = filp_clone_open(fmt->interp_file);
|
||||||
if (!IS_ERR(interp_file))
|
if (!IS_ERR(interp_file))
|
||||||
deny_write_access(interp_file);
|
deny_write_access(interp_file);
|
||||||
} else {
|
} else {
|
||||||
interp_file = open_exec(iname);
|
interp_file = open_exec(fmt->interpreter);
|
||||||
}
|
}
|
||||||
retval = PTR_ERR(interp_file);
|
retval = PTR_ERR(interp_file);
|
||||||
if (IS_ERR(interp_file))
|
if (IS_ERR(interp_file))
|
||||||
|
@ -238,6 +237,7 @@ static int load_misc_binary(struct linux_binprm *bprm)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
ret:
|
ret:
|
||||||
|
dput(fmt->dentry);
|
||||||
return retval;
|
return retval;
|
||||||
error:
|
error:
|
||||||
if (fd_binary > 0)
|
if (fd_binary > 0)
|
||||||
|
@ -594,8 +594,13 @@ static struct inode *bm_get_inode(struct super_block *sb, int mode)
|
||||||
|
|
||||||
static void bm_evict_inode(struct inode *inode)
|
static void bm_evict_inode(struct inode *inode)
|
||||||
{
|
{
|
||||||
|
Node *e = inode->i_private;
|
||||||
|
|
||||||
|
if (e->flags & MISC_FMT_OPEN_FILE)
|
||||||
|
filp_close(e->interp_file, NULL);
|
||||||
|
|
||||||
clear_inode(inode);
|
clear_inode(inode);
|
||||||
kfree(inode->i_private);
|
kfree(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void kill_node(Node *e)
|
static void kill_node(Node *e)
|
||||||
|
@ -603,24 +608,14 @@ static void kill_node(Node *e)
|
||||||
struct dentry *dentry;
|
struct dentry *dentry;
|
||||||
|
|
||||||
write_lock(&entries_lock);
|
write_lock(&entries_lock);
|
||||||
dentry = e->dentry;
|
list_del_init(&e->list);
|
||||||
if (dentry) {
|
|
||||||
list_del_init(&e->list);
|
|
||||||
e->dentry = NULL;
|
|
||||||
}
|
|
||||||
write_unlock(&entries_lock);
|
write_unlock(&entries_lock);
|
||||||
|
|
||||||
if ((e->flags & MISC_FMT_OPEN_FILE) && e->interp_file) {
|
dentry = e->dentry;
|
||||||
filp_close(e->interp_file, NULL);
|
drop_nlink(d_inode(dentry));
|
||||||
e->interp_file = NULL;
|
d_drop(dentry);
|
||||||
}
|
dput(dentry);
|
||||||
|
simple_release_fs(&bm_mnt, &entry_count);
|
||||||
if (dentry) {
|
|
||||||
drop_nlink(d_inode(dentry));
|
|
||||||
d_drop(dentry);
|
|
||||||
dput(dentry);
|
|
||||||
simple_release_fs(&bm_mnt, &entry_count);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* /<entry> */
|
/* /<entry> */
|
||||||
|
@ -665,7 +660,8 @@ static ssize_t bm_entry_write(struct file *file, const char __user *buffer,
|
||||||
root = file_inode(file)->i_sb->s_root;
|
root = file_inode(file)->i_sb->s_root;
|
||||||
inode_lock(d_inode(root));
|
inode_lock(d_inode(root));
|
||||||
|
|
||||||
kill_node(e);
|
if (!list_empty(&e->list))
|
||||||
|
kill_node(e);
|
||||||
|
|
||||||
inode_unlock(d_inode(root));
|
inode_unlock(d_inode(root));
|
||||||
break;
|
break;
|
||||||
|
@ -794,7 +790,7 @@ static ssize_t bm_status_write(struct file *file, const char __user *buffer,
|
||||||
inode_lock(d_inode(root));
|
inode_lock(d_inode(root));
|
||||||
|
|
||||||
while (!list_empty(&entries))
|
while (!list_empty(&entries))
|
||||||
kill_node(list_entry(entries.next, Node, list));
|
kill_node(list_first_entry(&entries, Node, list));
|
||||||
|
|
||||||
inode_unlock(d_inode(root));
|
inode_unlock(d_inode(root));
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -19,7 +19,6 @@ static int load_script(struct linux_binprm *bprm)
|
||||||
const char *i_arg, *i_name;
|
const char *i_arg, *i_name;
|
||||||
char *cp;
|
char *cp;
|
||||||
struct file *file;
|
struct file *file;
|
||||||
char interp[BINPRM_BUF_SIZE];
|
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!'))
|
if ((bprm->buf[0] != '#') || (bprm->buf[1] != '!'))
|
||||||
|
@ -55,7 +54,7 @@ static int load_script(struct linux_binprm *bprm)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
for (cp = bprm->buf+2; (*cp == ' ') || (*cp == '\t'); cp++);
|
for (cp = bprm->buf+2; (*cp == ' ') || (*cp == '\t'); cp++);
|
||||||
if (*cp == '\0')
|
if (*cp == '\0')
|
||||||
return -ENOEXEC; /* No interpreter name found */
|
return -ENOEXEC; /* No interpreter name found */
|
||||||
i_name = cp;
|
i_name = cp;
|
||||||
i_arg = NULL;
|
i_arg = NULL;
|
||||||
|
@ -65,7 +64,6 @@ static int load_script(struct linux_binprm *bprm)
|
||||||
*cp++ = '\0';
|
*cp++ = '\0';
|
||||||
if (*cp)
|
if (*cp)
|
||||||
i_arg = cp;
|
i_arg = cp;
|
||||||
strcpy (interp, i_name);
|
|
||||||
/*
|
/*
|
||||||
* OK, we've parsed out the interpreter name and
|
* OK, we've parsed out the interpreter name and
|
||||||
* (optional) argument.
|
* (optional) argument.
|
||||||
|
@ -80,24 +78,27 @@ static int load_script(struct linux_binprm *bprm)
|
||||||
if (retval)
|
if (retval)
|
||||||
return retval;
|
return retval;
|
||||||
retval = copy_strings_kernel(1, &bprm->interp, bprm);
|
retval = copy_strings_kernel(1, &bprm->interp, bprm);
|
||||||
if (retval < 0) return retval;
|
if (retval < 0)
|
||||||
|
return retval;
|
||||||
bprm->argc++;
|
bprm->argc++;
|
||||||
if (i_arg) {
|
if (i_arg) {
|
||||||
retval = copy_strings_kernel(1, &i_arg, bprm);
|
retval = copy_strings_kernel(1, &i_arg, bprm);
|
||||||
if (retval < 0) return retval;
|
if (retval < 0)
|
||||||
|
return retval;
|
||||||
bprm->argc++;
|
bprm->argc++;
|
||||||
}
|
}
|
||||||
retval = copy_strings_kernel(1, &i_name, bprm);
|
retval = copy_strings_kernel(1, &i_name, bprm);
|
||||||
if (retval) return retval;
|
if (retval)
|
||||||
|
return retval;
|
||||||
bprm->argc++;
|
bprm->argc++;
|
||||||
retval = bprm_change_interp(interp, bprm);
|
retval = bprm_change_interp(i_name, bprm);
|
||||||
if (retval < 0)
|
if (retval < 0)
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* OK, now restart the process with the interpreter's dentry.
|
* OK, now restart the process with the interpreter's dentry.
|
||||||
*/
|
*/
|
||||||
file = open_exec(interp);
|
file = open_exec(i_name);
|
||||||
if (IS_ERR(file))
|
if (IS_ERR(file))
|
||||||
return PTR_ERR(file);
|
return PTR_ERR(file);
|
||||||
|
|
||||||
|
|
|
@ -1410,7 +1410,7 @@ static void free_bprm(struct linux_binprm *bprm)
|
||||||
kfree(bprm);
|
kfree(bprm);
|
||||||
}
|
}
|
||||||
|
|
||||||
int bprm_change_interp(char *interp, struct linux_binprm *bprm)
|
int bprm_change_interp(const char *interp, struct linux_binprm *bprm)
|
||||||
{
|
{
|
||||||
/* If a binfmt changed the interp, free it first. */
|
/* If a binfmt changed the interp, free it first. */
|
||||||
if (bprm->interp != bprm->filename)
|
if (bprm->interp != bprm->filename)
|
||||||
|
|
|
@ -588,6 +588,12 @@ static void userfaultfd_event_wait_completion(struct userfaultfd_ctx *ctx,
|
||||||
break;
|
break;
|
||||||
if (ACCESS_ONCE(ctx->released) ||
|
if (ACCESS_ONCE(ctx->released) ||
|
||||||
fatal_signal_pending(current)) {
|
fatal_signal_pending(current)) {
|
||||||
|
/*
|
||||||
|
* &ewq->wq may be queued in fork_event, but
|
||||||
|
* __remove_wait_queue ignores the head
|
||||||
|
* parameter. It would be a problem if it
|
||||||
|
* didn't.
|
||||||
|
*/
|
||||||
__remove_wait_queue(&ctx->event_wqh, &ewq->wq);
|
__remove_wait_queue(&ctx->event_wqh, &ewq->wq);
|
||||||
if (ewq->msg.event == UFFD_EVENT_FORK) {
|
if (ewq->msg.event == UFFD_EVENT_FORK) {
|
||||||
struct userfaultfd_ctx *new;
|
struct userfaultfd_ctx *new;
|
||||||
|
@ -1061,6 +1067,12 @@ static ssize_t userfaultfd_ctx_read(struct userfaultfd_ctx *ctx, int no_wait,
|
||||||
(unsigned long)
|
(unsigned long)
|
||||||
uwq->msg.arg.reserved.reserved1;
|
uwq->msg.arg.reserved.reserved1;
|
||||||
list_move(&uwq->wq.entry, &fork_event);
|
list_move(&uwq->wq.entry, &fork_event);
|
||||||
|
/*
|
||||||
|
* fork_nctx can be freed as soon as
|
||||||
|
* we drop the lock, unless we take a
|
||||||
|
* reference on it.
|
||||||
|
*/
|
||||||
|
userfaultfd_ctx_get(fork_nctx);
|
||||||
spin_unlock(&ctx->event_wqh.lock);
|
spin_unlock(&ctx->event_wqh.lock);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
break;
|
break;
|
||||||
|
@ -1091,19 +1103,53 @@ static ssize_t userfaultfd_ctx_read(struct userfaultfd_ctx *ctx, int no_wait,
|
||||||
|
|
||||||
if (!ret && msg->event == UFFD_EVENT_FORK) {
|
if (!ret && msg->event == UFFD_EVENT_FORK) {
|
||||||
ret = resolve_userfault_fork(ctx, fork_nctx, msg);
|
ret = resolve_userfault_fork(ctx, fork_nctx, msg);
|
||||||
|
spin_lock(&ctx->event_wqh.lock);
|
||||||
|
if (!list_empty(&fork_event)) {
|
||||||
|
/*
|
||||||
|
* The fork thread didn't abort, so we can
|
||||||
|
* drop the temporary refcount.
|
||||||
|
*/
|
||||||
|
userfaultfd_ctx_put(fork_nctx);
|
||||||
|
|
||||||
if (!ret) {
|
uwq = list_first_entry(&fork_event,
|
||||||
spin_lock(&ctx->event_wqh.lock);
|
typeof(*uwq),
|
||||||
if (!list_empty(&fork_event)) {
|
wq.entry);
|
||||||
uwq = list_first_entry(&fork_event,
|
/*
|
||||||
typeof(*uwq),
|
* If fork_event list wasn't empty and in turn
|
||||||
wq.entry);
|
* the event wasn't already released by fork
|
||||||
list_del(&uwq->wq.entry);
|
* (the event is allocated on fork kernel
|
||||||
__add_wait_queue(&ctx->event_wqh, &uwq->wq);
|
* stack), put the event back to its place in
|
||||||
|
* the event_wq. fork_event head will be freed
|
||||||
|
* as soon as we return so the event cannot
|
||||||
|
* stay queued there no matter the current
|
||||||
|
* "ret" value.
|
||||||
|
*/
|
||||||
|
list_del(&uwq->wq.entry);
|
||||||
|
__add_wait_queue(&ctx->event_wqh, &uwq->wq);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Leave the event in the waitqueue and report
|
||||||
|
* error to userland if we failed to resolve
|
||||||
|
* the userfault fork.
|
||||||
|
*/
|
||||||
|
if (likely(!ret))
|
||||||
userfaultfd_event_complete(ctx, uwq);
|
userfaultfd_event_complete(ctx, uwq);
|
||||||
}
|
} else {
|
||||||
spin_unlock(&ctx->event_wqh.lock);
|
/*
|
||||||
|
* Here the fork thread aborted and the
|
||||||
|
* refcount from the fork thread on fork_nctx
|
||||||
|
* has already been released. We still hold
|
||||||
|
* the reference we took before releasing the
|
||||||
|
* lock above. If resolve_userfault_fork
|
||||||
|
* failed we've to drop it because the
|
||||||
|
* fork_nctx has to be freed in such case. If
|
||||||
|
* it succeeded we'll hold it because the new
|
||||||
|
* uffd references it.
|
||||||
|
*/
|
||||||
|
if (ret)
|
||||||
|
userfaultfd_ctx_put(fork_nctx);
|
||||||
}
|
}
|
||||||
|
spin_unlock(&ctx->event_wqh.lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -131,7 +131,7 @@ extern int setup_arg_pages(struct linux_binprm * bprm,
|
||||||
int executable_stack);
|
int executable_stack);
|
||||||
extern int transfer_args_to_stack(struct linux_binprm *bprm,
|
extern int transfer_args_to_stack(struct linux_binprm *bprm,
|
||||||
unsigned long *sp_location);
|
unsigned long *sp_location);
|
||||||
extern int bprm_change_interp(char *interp, struct linux_binprm *bprm);
|
extern int bprm_change_interp(const char *interp, struct linux_binprm *bprm);
|
||||||
extern int copy_strings_kernel(int argc, const char *const *argv,
|
extern int copy_strings_kernel(int argc, const char *const *argv,
|
||||||
struct linux_binprm *bprm);
|
struct linux_binprm *bprm);
|
||||||
extern int prepare_bprm_creds(struct linux_binprm *bprm);
|
extern int prepare_bprm_creds(struct linux_binprm *bprm);
|
||||||
|
|
|
@ -92,7 +92,7 @@
|
||||||
/**
|
/**
|
||||||
* FIELD_GET() - extract a bitfield element
|
* FIELD_GET() - extract a bitfield element
|
||||||
* @_mask: shifted mask defining the field's length and position
|
* @_mask: shifted mask defining the field's length and position
|
||||||
* @_reg: 32bit value of entire bitfield
|
* @_reg: value of entire bitfield
|
||||||
*
|
*
|
||||||
* FIELD_GET() extracts the field specified by @_mask from the
|
* FIELD_GET() extracts the field specified by @_mask from the
|
||||||
* bitfield passed in as @_reg by masking and shifting it down.
|
* bitfield passed in as @_reg by masking and shifting it down.
|
||||||
|
|
|
@ -403,7 +403,7 @@ struct address_space {
|
||||||
unsigned long flags; /* error bits */
|
unsigned long flags; /* error bits */
|
||||||
spinlock_t private_lock; /* for use by the address_space */
|
spinlock_t private_lock; /* for use by the address_space */
|
||||||
gfp_t gfp_mask; /* implicit gfp mask for allocations */
|
gfp_t gfp_mask; /* implicit gfp mask for allocations */
|
||||||
struct list_head private_list; /* ditto */
|
struct list_head private_list; /* for use by the address_space */
|
||||||
void *private_data; /* ditto */
|
void *private_data; /* ditto */
|
||||||
errseq_t wb_err;
|
errseq_t wb_err;
|
||||||
} __attribute__((aligned(sizeof(long)))) __randomize_layout;
|
} __attribute__((aligned(sizeof(long)))) __randomize_layout;
|
||||||
|
|
|
@ -240,7 +240,7 @@ extern unsigned int kobjsize(const void *objp);
|
||||||
|
|
||||||
#if defined(CONFIG_X86_INTEL_MPX)
|
#if defined(CONFIG_X86_INTEL_MPX)
|
||||||
/* MPX specific bounds table or bounds directory */
|
/* MPX specific bounds table or bounds directory */
|
||||||
# define VM_MPX VM_HIGH_ARCH_BIT_4
|
# define VM_MPX VM_HIGH_ARCH_4
|
||||||
#else
|
#else
|
||||||
# define VM_MPX VM_NONE
|
# define VM_MPX VM_NONE
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -400,6 +400,11 @@ extern void mmu_notifier_synchronize(void);
|
||||||
|
|
||||||
#else /* CONFIG_MMU_NOTIFIER */
|
#else /* CONFIG_MMU_NOTIFIER */
|
||||||
|
|
||||||
|
static inline int mm_has_notifiers(struct mm_struct *mm)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static inline void mmu_notifier_release(struct mm_struct *mm)
|
static inline void mmu_notifier_release(struct mm_struct *mm)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
|
@ -1094,8 +1094,14 @@ static inline unsigned long early_pfn_to_nid(unsigned long pfn)
|
||||||
#error Allocator MAX_ORDER exceeds SECTION_SIZE
|
#error Allocator MAX_ORDER exceeds SECTION_SIZE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define pfn_to_section_nr(pfn) ((pfn) >> PFN_SECTION_SHIFT)
|
static inline unsigned long pfn_to_section_nr(unsigned long pfn)
|
||||||
#define section_nr_to_pfn(sec) ((sec) << PFN_SECTION_SHIFT)
|
{
|
||||||
|
return pfn >> PFN_SECTION_SHIFT;
|
||||||
|
}
|
||||||
|
static inline unsigned long section_nr_to_pfn(unsigned long sec)
|
||||||
|
{
|
||||||
|
return sec << PFN_SECTION_SHIFT;
|
||||||
|
}
|
||||||
|
|
||||||
#define SECTION_ALIGN_UP(pfn) (((pfn) + PAGES_PER_SECTION - 1) & PAGE_SECTION_MASK)
|
#define SECTION_ALIGN_UP(pfn) (((pfn) + PAGES_PER_SECTION - 1) & PAGE_SECTION_MASK)
|
||||||
#define SECTION_ALIGN_DOWN(pfn) ((pfn) & PAGE_SECTION_MASK)
|
#define SECTION_ALIGN_DOWN(pfn) ((pfn) & PAGE_SECTION_MASK)
|
||||||
|
|
|
@ -84,6 +84,12 @@ static inline bool mmget_not_zero(struct mm_struct *mm)
|
||||||
|
|
||||||
/* mmput gets rid of the mappings and all user-space */
|
/* mmput gets rid of the mappings and all user-space */
|
||||||
extern void mmput(struct mm_struct *);
|
extern void mmput(struct mm_struct *);
|
||||||
|
#ifdef CONFIG_MMU
|
||||||
|
/* same as above but performs the slow path from the async context. Can
|
||||||
|
* be called from the atomic context as well
|
||||||
|
*/
|
||||||
|
void mmput_async(struct mm_struct *);
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Grab a reference to a task's mm, if it is not already going away */
|
/* Grab a reference to a task's mm, if it is not already going away */
|
||||||
extern struct mm_struct *get_task_mm(struct task_struct *task);
|
extern struct mm_struct *get_task_mm(struct task_struct *task);
|
||||||
|
|
|
@ -946,6 +946,24 @@ void mmput(struct mm_struct *mm)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(mmput);
|
EXPORT_SYMBOL_GPL(mmput);
|
||||||
|
|
||||||
|
#ifdef CONFIG_MMU
|
||||||
|
static void mmput_async_fn(struct work_struct *work)
|
||||||
|
{
|
||||||
|
struct mm_struct *mm = container_of(work, struct mm_struct,
|
||||||
|
async_put_work);
|
||||||
|
|
||||||
|
__mmput(mm);
|
||||||
|
}
|
||||||
|
|
||||||
|
void mmput_async(struct mm_struct *mm)
|
||||||
|
{
|
||||||
|
if (atomic_dec_and_test(&mm->mm_users)) {
|
||||||
|
INIT_WORK(&mm->async_put_work, mmput_async_fn);
|
||||||
|
schedule_work(&mm->async_put_work);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* set_mm_exe_file - change a reference to the mm's executable file
|
* set_mm_exe_file - change a reference to the mm's executable file
|
||||||
*
|
*
|
||||||
|
|
|
@ -131,7 +131,7 @@ static int kcmp_epoll_target(struct task_struct *task1,
|
||||||
if (filp_epoll) {
|
if (filp_epoll) {
|
||||||
filp_tgt = get_epoll_tfile_raw_ptr(filp_epoll, slot.tfd, slot.toff);
|
filp_tgt = get_epoll_tfile_raw_ptr(filp_epoll, slot.tfd, slot.toff);
|
||||||
fput(filp_epoll);
|
fput(filp_epoll);
|
||||||
} else
|
}
|
||||||
|
|
||||||
if (IS_ERR(filp_tgt))
|
if (IS_ERR(filp_tgt))
|
||||||
return PTR_ERR(filp_tgt);
|
return PTR_ERR(filp_tgt);
|
||||||
|
|
|
@ -350,7 +350,7 @@ void *devm_memremap_pages(struct device *dev, struct resource *res,
|
||||||
pgprot_t pgprot = PAGE_KERNEL;
|
pgprot_t pgprot = PAGE_KERNEL;
|
||||||
struct dev_pagemap *pgmap;
|
struct dev_pagemap *pgmap;
|
||||||
struct page_map *page_map;
|
struct page_map *page_map;
|
||||||
int error, nid, is_ram;
|
int error, nid, is_ram, i = 0;
|
||||||
|
|
||||||
align_start = res->start & ~(SECTION_SIZE - 1);
|
align_start = res->start & ~(SECTION_SIZE - 1);
|
||||||
align_size = ALIGN(res->start + resource_size(res), SECTION_SIZE)
|
align_size = ALIGN(res->start + resource_size(res), SECTION_SIZE)
|
||||||
|
@ -448,6 +448,8 @@ void *devm_memremap_pages(struct device *dev, struct resource *res,
|
||||||
list_del(&page->lru);
|
list_del(&page->lru);
|
||||||
page->pgmap = pgmap;
|
page->pgmap = pgmap;
|
||||||
percpu_ref_get(ref);
|
percpu_ref_get(ref);
|
||||||
|
if (!(++i % 1024))
|
||||||
|
cond_resched();
|
||||||
}
|
}
|
||||||
devres_add(dev, page_map);
|
devres_add(dev, page_map);
|
||||||
return __va(res->start);
|
return __va(res->start);
|
||||||
|
|
|
@ -224,7 +224,7 @@ char *parse_args(const char *doing,
|
||||||
} \
|
} \
|
||||||
int param_get_##name(char *buffer, const struct kernel_param *kp) \
|
int param_get_##name(char *buffer, const struct kernel_param *kp) \
|
||||||
{ \
|
{ \
|
||||||
return scnprintf(buffer, PAGE_SIZE, format, \
|
return scnprintf(buffer, PAGE_SIZE, format "\n", \
|
||||||
*((type *)kp->arg)); \
|
*((type *)kp->arg)); \
|
||||||
} \
|
} \
|
||||||
const struct kernel_param_ops param_ops_##name = { \
|
const struct kernel_param_ops param_ops_##name = { \
|
||||||
|
@ -236,14 +236,14 @@ char *parse_args(const char *doing,
|
||||||
EXPORT_SYMBOL(param_ops_##name)
|
EXPORT_SYMBOL(param_ops_##name)
|
||||||
|
|
||||||
|
|
||||||
STANDARD_PARAM_DEF(byte, unsigned char, "%hhu", kstrtou8);
|
STANDARD_PARAM_DEF(byte, unsigned char, "%hhu", kstrtou8);
|
||||||
STANDARD_PARAM_DEF(short, short, "%hi", kstrtos16);
|
STANDARD_PARAM_DEF(short, short, "%hi", kstrtos16);
|
||||||
STANDARD_PARAM_DEF(ushort, unsigned short, "%hu", kstrtou16);
|
STANDARD_PARAM_DEF(ushort, unsigned short, "%hu", kstrtou16);
|
||||||
STANDARD_PARAM_DEF(int, int, "%i", kstrtoint);
|
STANDARD_PARAM_DEF(int, int, "%i", kstrtoint);
|
||||||
STANDARD_PARAM_DEF(uint, unsigned int, "%u", kstrtouint);
|
STANDARD_PARAM_DEF(uint, unsigned int, "%u", kstrtouint);
|
||||||
STANDARD_PARAM_DEF(long, long, "%li", kstrtol);
|
STANDARD_PARAM_DEF(long, long, "%li", kstrtol);
|
||||||
STANDARD_PARAM_DEF(ulong, unsigned long, "%lu", kstrtoul);
|
STANDARD_PARAM_DEF(ulong, unsigned long, "%lu", kstrtoul);
|
||||||
STANDARD_PARAM_DEF(ullong, unsigned long long, "%llu", kstrtoull);
|
STANDARD_PARAM_DEF(ullong, unsigned long long, "%llu", kstrtoull);
|
||||||
|
|
||||||
int param_set_charp(const char *val, const struct kernel_param *kp)
|
int param_set_charp(const char *val, const struct kernel_param *kp)
|
||||||
{
|
{
|
||||||
|
@ -270,7 +270,7 @@ EXPORT_SYMBOL(param_set_charp);
|
||||||
|
|
||||||
int param_get_charp(char *buffer, const struct kernel_param *kp)
|
int param_get_charp(char *buffer, const struct kernel_param *kp)
|
||||||
{
|
{
|
||||||
return scnprintf(buffer, PAGE_SIZE, "%s", *((char **)kp->arg));
|
return scnprintf(buffer, PAGE_SIZE, "%s\n", *((char **)kp->arg));
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(param_get_charp);
|
EXPORT_SYMBOL(param_get_charp);
|
||||||
|
|
||||||
|
@ -301,7 +301,7 @@ EXPORT_SYMBOL(param_set_bool);
|
||||||
int param_get_bool(char *buffer, const struct kernel_param *kp)
|
int param_get_bool(char *buffer, const struct kernel_param *kp)
|
||||||
{
|
{
|
||||||
/* Y and N chosen as being relatively non-coder friendly */
|
/* Y and N chosen as being relatively non-coder friendly */
|
||||||
return sprintf(buffer, "%c", *(bool *)kp->arg ? 'Y' : 'N');
|
return sprintf(buffer, "%c\n", *(bool *)kp->arg ? 'Y' : 'N');
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(param_get_bool);
|
EXPORT_SYMBOL(param_get_bool);
|
||||||
|
|
||||||
|
@ -360,7 +360,7 @@ EXPORT_SYMBOL(param_set_invbool);
|
||||||
|
|
||||||
int param_get_invbool(char *buffer, const struct kernel_param *kp)
|
int param_get_invbool(char *buffer, const struct kernel_param *kp)
|
||||||
{
|
{
|
||||||
return sprintf(buffer, "%c", (*(bool *)kp->arg) ? 'N' : 'Y');
|
return sprintf(buffer, "%c\n", (*(bool *)kp->arg) ? 'N' : 'Y');
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(param_get_invbool);
|
EXPORT_SYMBOL(param_get_invbool);
|
||||||
|
|
||||||
|
@ -460,8 +460,9 @@ static int param_array_get(char *buffer, const struct kernel_param *kp)
|
||||||
struct kernel_param p = *kp;
|
struct kernel_param p = *kp;
|
||||||
|
|
||||||
for (i = off = 0; i < (arr->num ? *arr->num : arr->max); i++) {
|
for (i = off = 0; i < (arr->num ? *arr->num : arr->max); i++) {
|
||||||
|
/* Replace \n with comma */
|
||||||
if (i)
|
if (i)
|
||||||
buffer[off++] = ',';
|
buffer[off - 1] = ',';
|
||||||
p.arg = arr->elem + arr->elemsize * i;
|
p.arg = arr->elem + arr->elemsize * i;
|
||||||
check_kparam_locked(p.mod);
|
check_kparam_locked(p.mod);
|
||||||
ret = arr->ops->get(buffer + off, &p);
|
ret = arr->ops->get(buffer + off, &p);
|
||||||
|
@ -507,7 +508,7 @@ EXPORT_SYMBOL(param_set_copystring);
|
||||||
int param_get_string(char *buffer, const struct kernel_param *kp)
|
int param_get_string(char *buffer, const struct kernel_param *kp)
|
||||||
{
|
{
|
||||||
const struct kparam_string *kps = kp->str;
|
const struct kparam_string *kps = kp->str;
|
||||||
return strlcpy(buffer, kps->string, kps->maxlen);
|
return scnprintf(buffer, PAGE_SIZE, "%s\n", kps->string);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(param_get_string);
|
EXPORT_SYMBOL(param_get_string);
|
||||||
|
|
||||||
|
@ -549,10 +550,6 @@ static ssize_t param_attr_show(struct module_attribute *mattr,
|
||||||
kernel_param_lock(mk->mod);
|
kernel_param_lock(mk->mod);
|
||||||
count = attribute->param->ops->get(buf, attribute->param);
|
count = attribute->param->ops->get(buf, attribute->param);
|
||||||
kernel_param_unlock(mk->mod);
|
kernel_param_unlock(mk->mod);
|
||||||
if (count > 0) {
|
|
||||||
strcat(buf, "\n");
|
|
||||||
++count;
|
|
||||||
}
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -600,7 +597,7 @@ EXPORT_SYMBOL(kernel_param_unlock);
|
||||||
/*
|
/*
|
||||||
* add_sysfs_param - add a parameter to sysfs
|
* add_sysfs_param - add a parameter to sysfs
|
||||||
* @mk: struct module_kobject
|
* @mk: struct module_kobject
|
||||||
* @kparam: the actual parameter definition to add to sysfs
|
* @kp: the actual parameter definition to add to sysfs
|
||||||
* @name: name of parameter
|
* @name: name of parameter
|
||||||
*
|
*
|
||||||
* Create a kobject if for a (per-module) parameter if mp NULL, and
|
* Create a kobject if for a (per-module) parameter if mp NULL, and
|
||||||
|
|
|
@ -2186,8 +2186,6 @@ static int do_proc_douintvec_conv(unsigned long *lvalp,
|
||||||
int write, void *data)
|
int write, void *data)
|
||||||
{
|
{
|
||||||
if (write) {
|
if (write) {
|
||||||
if (*lvalp > UINT_MAX)
|
|
||||||
return -EINVAL;
|
|
||||||
if (*lvalp > UINT_MAX)
|
if (*lvalp > UINT_MAX)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
*valp = *lvalp;
|
*valp = *lvalp;
|
||||||
|
|
|
@ -146,8 +146,8 @@ EXPORT_SYMBOL(idr_get_next_ext);
|
||||||
* idr_alloc() and idr_remove() (as long as the ID being removed is not
|
* idr_alloc() and idr_remove() (as long as the ID being removed is not
|
||||||
* the one being replaced!).
|
* the one being replaced!).
|
||||||
*
|
*
|
||||||
* Returns: 0 on success. %-ENOENT indicates that @id was not found.
|
* Returns: the old value on success. %-ENOENT indicates that @id was not
|
||||||
* %-EINVAL indicates that @id or @ptr were not valid.
|
* found. %-EINVAL indicates that @id or @ptr were not valid.
|
||||||
*/
|
*/
|
||||||
void *idr_replace(struct idr *idr, void *ptr, int id)
|
void *idr_replace(struct idr *idr, void *ptr, int id)
|
||||||
{
|
{
|
||||||
|
|
|
@ -85,8 +85,8 @@ static FORCE_INLINE int LZ4_decompress_generic(
|
||||||
const BYTE * const lowLimit = lowPrefix - dictSize;
|
const BYTE * const lowLimit = lowPrefix - dictSize;
|
||||||
|
|
||||||
const BYTE * const dictEnd = (const BYTE *)dictStart + dictSize;
|
const BYTE * const dictEnd = (const BYTE *)dictStart + dictSize;
|
||||||
const unsigned int dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 };
|
static const unsigned int dec32table[] = { 0, 1, 2, 1, 4, 4, 4, 4 };
|
||||||
const int dec64table[] = { 0, 0, 0, -1, 0, 1, 2, 3 };
|
static const int dec64table[] = { 0, 0, 0, -1, 0, 1, 2, 3 };
|
||||||
|
|
||||||
const int safeDecode = (endOnInput == endOnInputSize);
|
const int safeDecode = (endOnInput == endOnInputSize);
|
||||||
const int checkOffset = ((safeDecode) && (dictSize < (int)(64 * KB)));
|
const int checkOffset = ((safeDecode) && (dictSize < (int)(64 * KB)));
|
||||||
|
|
|
@ -48,7 +48,9 @@ int ___ratelimit(struct ratelimit_state *rs, const char *func)
|
||||||
if (time_is_before_jiffies(rs->begin + rs->interval)) {
|
if (time_is_before_jiffies(rs->begin + rs->interval)) {
|
||||||
if (rs->missed) {
|
if (rs->missed) {
|
||||||
if (!(rs->flags & RATELIMIT_MSG_ON_RELEASE)) {
|
if (!(rs->flags & RATELIMIT_MSG_ON_RELEASE)) {
|
||||||
pr_warn("%s: %d callbacks suppressed\n", func, rs->missed);
|
printk_deferred(KERN_WARNING
|
||||||
|
"%s: %d callbacks suppressed\n",
|
||||||
|
func, rs->missed);
|
||||||
rs->missed = 0;
|
rs->missed = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1999,17 +1999,14 @@ void wakeup_kcompactd(pg_data_t *pgdat, int order, int classzone_idx)
|
||||||
if (pgdat->kcompactd_max_order < order)
|
if (pgdat->kcompactd_max_order < order)
|
||||||
pgdat->kcompactd_max_order = order;
|
pgdat->kcompactd_max_order = order;
|
||||||
|
|
||||||
/*
|
|
||||||
* Pairs with implicit barrier in wait_event_freezable()
|
|
||||||
* such that wakeups are not missed in the lockless
|
|
||||||
* waitqueue_active() call.
|
|
||||||
*/
|
|
||||||
smp_acquire__after_ctrl_dep();
|
|
||||||
|
|
||||||
if (pgdat->kcompactd_classzone_idx > classzone_idx)
|
if (pgdat->kcompactd_classzone_idx > classzone_idx)
|
||||||
pgdat->kcompactd_classzone_idx = classzone_idx;
|
pgdat->kcompactd_classzone_idx = classzone_idx;
|
||||||
|
|
||||||
if (!waitqueue_active(&pgdat->kcompactd_wait))
|
/*
|
||||||
|
* Pairs with implicit barrier in wait_event_freezable()
|
||||||
|
* such that wakeups are not missed.
|
||||||
|
*/
|
||||||
|
if (!wq_has_sleeper(&pgdat->kcompactd_wait))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!kcompactd_node_suitable(pgdat))
|
if (!kcompactd_node_suitable(pgdat))
|
||||||
|
|
|
@ -620,6 +620,14 @@ int file_check_and_advance_wb_err(struct file *file)
|
||||||
trace_file_check_and_advance_wb_err(file, old);
|
trace_file_check_and_advance_wb_err(file, old);
|
||||||
spin_unlock(&file->f_lock);
|
spin_unlock(&file->f_lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We're mostly using this function as a drop in replacement for
|
||||||
|
* filemap_check_errors. Clear AS_EIO/AS_ENOSPC to emulate the effect
|
||||||
|
* that the legacy code would have had on these flags.
|
||||||
|
*/
|
||||||
|
clear_bit(AS_EIO, &mapping->flags);
|
||||||
|
clear_bit(AS_ENOSPC, &mapping->flags);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(file_check_and_advance_wb_err);
|
EXPORT_SYMBOL(file_check_and_advance_wb_err);
|
||||||
|
|
5
mm/ksm.c
5
mm/ksm.c
|
@ -1990,6 +1990,7 @@ static void stable_tree_append(struct rmap_item *rmap_item,
|
||||||
*/
|
*/
|
||||||
static void cmp_and_merge_page(struct page *page, struct rmap_item *rmap_item)
|
static void cmp_and_merge_page(struct page *page, struct rmap_item *rmap_item)
|
||||||
{
|
{
|
||||||
|
struct mm_struct *mm = rmap_item->mm;
|
||||||
struct rmap_item *tree_rmap_item;
|
struct rmap_item *tree_rmap_item;
|
||||||
struct page *tree_page = NULL;
|
struct page *tree_page = NULL;
|
||||||
struct stable_node *stable_node;
|
struct stable_node *stable_node;
|
||||||
|
@ -2062,9 +2063,11 @@ static void cmp_and_merge_page(struct page *page, struct rmap_item *rmap_item)
|
||||||
if (ksm_use_zero_pages && (checksum == zero_checksum)) {
|
if (ksm_use_zero_pages && (checksum == zero_checksum)) {
|
||||||
struct vm_area_struct *vma;
|
struct vm_area_struct *vma;
|
||||||
|
|
||||||
vma = find_mergeable_vma(rmap_item->mm, rmap_item->address);
|
down_read(&mm->mmap_sem);
|
||||||
|
vma = find_mergeable_vma(mm, rmap_item->address);
|
||||||
err = try_to_merge_one_page(vma, page,
|
err = try_to_merge_one_page(vma, page,
|
||||||
ZERO_PAGE(rmap_item->address));
|
ZERO_PAGE(rmap_item->address));
|
||||||
|
up_read(&mm->mmap_sem);
|
||||||
/*
|
/*
|
||||||
* In case of failure, the page was not really empty, so we
|
* In case of failure, the page was not really empty, so we
|
||||||
* need to continue. Otherwise we're done.
|
* need to continue. Otherwise we're done.
|
||||||
|
|
|
@ -325,12 +325,12 @@ static int memcg_init_list_lru_node(struct list_lru_node *nlru)
|
||||||
{
|
{
|
||||||
int size = memcg_nr_cache_ids;
|
int size = memcg_nr_cache_ids;
|
||||||
|
|
||||||
nlru->memcg_lrus = kmalloc(size * sizeof(void *), GFP_KERNEL);
|
nlru->memcg_lrus = kvmalloc(size * sizeof(void *), GFP_KERNEL);
|
||||||
if (!nlru->memcg_lrus)
|
if (!nlru->memcg_lrus)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
if (__memcg_init_list_lru_node(nlru->memcg_lrus, 0, size)) {
|
if (__memcg_init_list_lru_node(nlru->memcg_lrus, 0, size)) {
|
||||||
kfree(nlru->memcg_lrus);
|
kvfree(nlru->memcg_lrus);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -340,7 +340,7 @@ static int memcg_init_list_lru_node(struct list_lru_node *nlru)
|
||||||
static void memcg_destroy_list_lru_node(struct list_lru_node *nlru)
|
static void memcg_destroy_list_lru_node(struct list_lru_node *nlru)
|
||||||
{
|
{
|
||||||
__memcg_destroy_list_lru_node(nlru->memcg_lrus, 0, memcg_nr_cache_ids);
|
__memcg_destroy_list_lru_node(nlru->memcg_lrus, 0, memcg_nr_cache_ids);
|
||||||
kfree(nlru->memcg_lrus);
|
kvfree(nlru->memcg_lrus);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int memcg_update_list_lru_node(struct list_lru_node *nlru,
|
static int memcg_update_list_lru_node(struct list_lru_node *nlru,
|
||||||
|
@ -351,12 +351,12 @@ static int memcg_update_list_lru_node(struct list_lru_node *nlru,
|
||||||
BUG_ON(old_size > new_size);
|
BUG_ON(old_size > new_size);
|
||||||
|
|
||||||
old = nlru->memcg_lrus;
|
old = nlru->memcg_lrus;
|
||||||
new = kmalloc(new_size * sizeof(void *), GFP_KERNEL);
|
new = kvmalloc(new_size * sizeof(void *), GFP_KERNEL);
|
||||||
if (!new)
|
if (!new)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
if (__memcg_init_list_lru_node(new, old_size, new_size)) {
|
if (__memcg_init_list_lru_node(new, old_size, new_size)) {
|
||||||
kfree(new);
|
kvfree(new);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -373,7 +373,7 @@ static int memcg_update_list_lru_node(struct list_lru_node *nlru,
|
||||||
nlru->memcg_lrus = new;
|
nlru->memcg_lrus = new;
|
||||||
spin_unlock_irq(&nlru->lock);
|
spin_unlock_irq(&nlru->lock);
|
||||||
|
|
||||||
kfree(old);
|
kvfree(old);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
12
mm/madvise.c
12
mm/madvise.c
|
@ -625,18 +625,26 @@ static int madvise_inject_error(int behavior,
|
||||||
{
|
{
|
||||||
struct page *page;
|
struct page *page;
|
||||||
struct zone *zone;
|
struct zone *zone;
|
||||||
|
unsigned int order;
|
||||||
|
|
||||||
if (!capable(CAP_SYS_ADMIN))
|
if (!capable(CAP_SYS_ADMIN))
|
||||||
return -EPERM;
|
return -EPERM;
|
||||||
|
|
||||||
for (; start < end; start += PAGE_SIZE <<
|
|
||||||
compound_order(compound_head(page))) {
|
for (; start < end; start += PAGE_SIZE << order) {
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = get_user_pages_fast(start, 1, 0, &page);
|
ret = get_user_pages_fast(start, 1, 0, &page);
|
||||||
if (ret != 1)
|
if (ret != 1)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* When soft offlining hugepages, after migrating the page
|
||||||
|
* we dissolve it, therefore in the second loop "page" will
|
||||||
|
* no longer be a compound page, and order will be 0.
|
||||||
|
*/
|
||||||
|
order = compound_order(compound_head(page));
|
||||||
|
|
||||||
if (PageHWPoison(page)) {
|
if (PageHWPoison(page)) {
|
||||||
put_page(page);
|
put_page(page);
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -1777,6 +1777,10 @@ static void drain_local_stock(struct work_struct *dummy)
|
||||||
struct memcg_stock_pcp *stock;
|
struct memcg_stock_pcp *stock;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The only protection from memory hotplug vs. drain_stock races is
|
||||||
|
* that we always operate on local CPU stock here with IRQ disabled
|
||||||
|
*/
|
||||||
local_irq_save(flags);
|
local_irq_save(flags);
|
||||||
|
|
||||||
stock = this_cpu_ptr(&memcg_stock);
|
stock = this_cpu_ptr(&memcg_stock);
|
||||||
|
@ -1821,27 +1825,33 @@ static void drain_all_stock(struct mem_cgroup *root_memcg)
|
||||||
/* If someone's already draining, avoid adding running more workers. */
|
/* If someone's already draining, avoid adding running more workers. */
|
||||||
if (!mutex_trylock(&percpu_charge_mutex))
|
if (!mutex_trylock(&percpu_charge_mutex))
|
||||||
return;
|
return;
|
||||||
/* Notify other cpus that system-wide "drain" is running */
|
/*
|
||||||
get_online_cpus();
|
* Notify other cpus that system-wide "drain" is running
|
||||||
|
* We do not care about races with the cpu hotplug because cpu down
|
||||||
|
* as well as workers from this path always operate on the local
|
||||||
|
* per-cpu data. CPU up doesn't touch memcg_stock at all.
|
||||||
|
*/
|
||||||
curcpu = get_cpu();
|
curcpu = get_cpu();
|
||||||
for_each_online_cpu(cpu) {
|
for_each_online_cpu(cpu) {
|
||||||
struct memcg_stock_pcp *stock = &per_cpu(memcg_stock, cpu);
|
struct memcg_stock_pcp *stock = &per_cpu(memcg_stock, cpu);
|
||||||
struct mem_cgroup *memcg;
|
struct mem_cgroup *memcg;
|
||||||
|
|
||||||
memcg = stock->cached;
|
memcg = stock->cached;
|
||||||
if (!memcg || !stock->nr_pages)
|
if (!memcg || !stock->nr_pages || !css_tryget(&memcg->css))
|
||||||
continue;
|
continue;
|
||||||
if (!mem_cgroup_is_descendant(memcg, root_memcg))
|
if (!mem_cgroup_is_descendant(memcg, root_memcg)) {
|
||||||
|
css_put(&memcg->css);
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
if (!test_and_set_bit(FLUSHING_CACHED_CHARGE, &stock->flags)) {
|
if (!test_and_set_bit(FLUSHING_CACHED_CHARGE, &stock->flags)) {
|
||||||
if (cpu == curcpu)
|
if (cpu == curcpu)
|
||||||
drain_local_stock(&stock->work);
|
drain_local_stock(&stock->work);
|
||||||
else
|
else
|
||||||
schedule_work_on(cpu, &stock->work);
|
schedule_work_on(cpu, &stock->work);
|
||||||
}
|
}
|
||||||
|
css_put(&memcg->css);
|
||||||
}
|
}
|
||||||
put_cpu();
|
put_cpu();
|
||||||
put_online_cpus();
|
|
||||||
mutex_unlock(&percpu_charge_mutex);
|
mutex_unlock(&percpu_charge_mutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5648,7 +5658,8 @@ static void uncharge_batch(const struct uncharge_gather *ug)
|
||||||
static void uncharge_page(struct page *page, struct uncharge_gather *ug)
|
static void uncharge_page(struct page *page, struct uncharge_gather *ug)
|
||||||
{
|
{
|
||||||
VM_BUG_ON_PAGE(PageLRU(page), page);
|
VM_BUG_ON_PAGE(PageLRU(page), page);
|
||||||
VM_BUG_ON_PAGE(!PageHWPoison(page) && page_count(page), page);
|
VM_BUG_ON_PAGE(page_count(page) && !is_zone_device_page(page) &&
|
||||||
|
!PageHWPoison(page) , page);
|
||||||
|
|
||||||
if (!page->mem_cgroup)
|
if (!page->mem_cgroup)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -845,7 +845,7 @@ struct page *_vm_normal_page(struct vm_area_struct *vma, unsigned long addr,
|
||||||
* vm_normal_page() so that we do not have to special case all
|
* vm_normal_page() so that we do not have to special case all
|
||||||
* call site of vm_normal_page().
|
* call site of vm_normal_page().
|
||||||
*/
|
*/
|
||||||
if (likely(pfn < highest_memmap_pfn)) {
|
if (likely(pfn <= highest_memmap_pfn)) {
|
||||||
struct page *page = pfn_to_page(pfn);
|
struct page *page = pfn_to_page(pfn);
|
||||||
|
|
||||||
if (is_device_public_page(page)) {
|
if (is_device_public_page(page)) {
|
||||||
|
|
|
@ -328,6 +328,7 @@ int __ref __add_pages(int nid, unsigned long phys_start_pfn,
|
||||||
if (err && (err != -EEXIST))
|
if (err && (err != -EEXIST))
|
||||||
break;
|
break;
|
||||||
err = 0;
|
err = 0;
|
||||||
|
cond_resched();
|
||||||
}
|
}
|
||||||
vmemmap_populate_print_last();
|
vmemmap_populate_print_last();
|
||||||
out:
|
out:
|
||||||
|
@ -337,7 +338,7 @@ EXPORT_SYMBOL_GPL(__add_pages);
|
||||||
|
|
||||||
#ifdef CONFIG_MEMORY_HOTREMOVE
|
#ifdef CONFIG_MEMORY_HOTREMOVE
|
||||||
/* find the smallest valid pfn in the range [start_pfn, end_pfn) */
|
/* find the smallest valid pfn in the range [start_pfn, end_pfn) */
|
||||||
static int find_smallest_section_pfn(int nid, struct zone *zone,
|
static unsigned long find_smallest_section_pfn(int nid, struct zone *zone,
|
||||||
unsigned long start_pfn,
|
unsigned long start_pfn,
|
||||||
unsigned long end_pfn)
|
unsigned long end_pfn)
|
||||||
{
|
{
|
||||||
|
@ -362,7 +363,7 @@ static int find_smallest_section_pfn(int nid, struct zone *zone,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* find the biggest valid pfn in the range [start_pfn, end_pfn). */
|
/* find the biggest valid pfn in the range [start_pfn, end_pfn). */
|
||||||
static int find_biggest_section_pfn(int nid, struct zone *zone,
|
static unsigned long find_biggest_section_pfn(int nid, struct zone *zone,
|
||||||
unsigned long start_pfn,
|
unsigned long start_pfn,
|
||||||
unsigned long end_pfn)
|
unsigned long end_pfn)
|
||||||
{
|
{
|
||||||
|
@ -550,7 +551,7 @@ static int __remove_section(struct zone *zone, struct mem_section *ms,
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
scn_nr = __section_nr(ms);
|
scn_nr = __section_nr(ms);
|
||||||
start_pfn = section_nr_to_pfn(scn_nr);
|
start_pfn = section_nr_to_pfn((unsigned long)scn_nr);
|
||||||
__remove_zone(zone, start_pfn);
|
__remove_zone(zone, start_pfn);
|
||||||
|
|
||||||
sparse_remove_one_section(zone, ms, map_offset);
|
sparse_remove_one_section(zone, ms, map_offset);
|
||||||
|
|
|
@ -40,6 +40,7 @@
|
||||||
#include <linux/ratelimit.h>
|
#include <linux/ratelimit.h>
|
||||||
#include <linux/kthread.h>
|
#include <linux/kthread.h>
|
||||||
#include <linux/init.h>
|
#include <linux/init.h>
|
||||||
|
#include <linux/mmu_notifier.h>
|
||||||
|
|
||||||
#include <asm/tlb.h>
|
#include <asm/tlb.h>
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
@ -494,6 +495,21 @@ static bool __oom_reap_task_mm(struct task_struct *tsk, struct mm_struct *mm)
|
||||||
goto unlock_oom;
|
goto unlock_oom;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the mm has notifiers then we would need to invalidate them around
|
||||||
|
* unmap_page_range and that is risky because notifiers can sleep and
|
||||||
|
* what they do is basically undeterministic. So let's have a short
|
||||||
|
* sleep to give the oom victim some more time.
|
||||||
|
* TODO: we really want to get rid of this ugly hack and make sure that
|
||||||
|
* notifiers cannot block for unbounded amount of time and add
|
||||||
|
* mmu_notifier_invalidate_range_{start,end} around unmap_page_range
|
||||||
|
*/
|
||||||
|
if (mm_has_notifiers(mm)) {
|
||||||
|
up_read(&mm->mmap_sem);
|
||||||
|
schedule_timeout_idle(HZ);
|
||||||
|
goto unlock_oom;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* MMF_OOM_SKIP is set by exit_mmap when the OOM reaper can't
|
* MMF_OOM_SKIP is set by exit_mmap when the OOM reaper can't
|
||||||
* work on the mm anymore. The check for MMF_OOM_SKIP must run
|
* work on the mm anymore. The check for MMF_OOM_SKIP must run
|
||||||
|
|
|
@ -1190,7 +1190,7 @@ static void __meminit __init_single_pfn(unsigned long pfn, unsigned long zone,
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_DEFERRED_STRUCT_PAGE_INIT
|
#ifdef CONFIG_DEFERRED_STRUCT_PAGE_INIT
|
||||||
static void init_reserved_page(unsigned long pfn)
|
static void __meminit init_reserved_page(unsigned long pfn)
|
||||||
{
|
{
|
||||||
pg_data_t *pgdat;
|
pg_data_t *pgdat;
|
||||||
int nid, zid;
|
int nid, zid;
|
||||||
|
@ -5367,6 +5367,7 @@ not_early:
|
||||||
|
|
||||||
__init_single_page(page, pfn, zone, nid);
|
__init_single_page(page, pfn, zone, nid);
|
||||||
set_pageblock_migratetype(page, MIGRATE_MOVABLE);
|
set_pageblock_migratetype(page, MIGRATE_MOVABLE);
|
||||||
|
cond_resched();
|
||||||
} else {
|
} else {
|
||||||
__init_single_pfn(pfn, zone, nid);
|
__init_single_pfn(pfn, zone, nid);
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
#include <linux/uaccess.h>
|
#include <linux/uaccess.h>
|
||||||
#include <asm/sections.h>
|
#include <asm/sections.h>
|
||||||
|
|
||||||
const int rodata_test_data = 0xC3;
|
static const int rodata_test_data = 0xC3;
|
||||||
|
|
||||||
void rodata_test(void)
|
void rodata_test(void)
|
||||||
{
|
{
|
||||||
|
|
|
@ -165,9 +165,9 @@ static int init_memcg_params(struct kmem_cache *s,
|
||||||
if (!memcg_nr_cache_ids)
|
if (!memcg_nr_cache_ids)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
arr = kzalloc(sizeof(struct memcg_cache_array) +
|
arr = kvzalloc(sizeof(struct memcg_cache_array) +
|
||||||
memcg_nr_cache_ids * sizeof(void *),
|
memcg_nr_cache_ids * sizeof(void *),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!arr)
|
if (!arr)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
@ -178,15 +178,23 @@ static int init_memcg_params(struct kmem_cache *s,
|
||||||
static void destroy_memcg_params(struct kmem_cache *s)
|
static void destroy_memcg_params(struct kmem_cache *s)
|
||||||
{
|
{
|
||||||
if (is_root_cache(s))
|
if (is_root_cache(s))
|
||||||
kfree(rcu_access_pointer(s->memcg_params.memcg_caches));
|
kvfree(rcu_access_pointer(s->memcg_params.memcg_caches));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void free_memcg_params(struct rcu_head *rcu)
|
||||||
|
{
|
||||||
|
struct memcg_cache_array *old;
|
||||||
|
|
||||||
|
old = container_of(rcu, struct memcg_cache_array, rcu);
|
||||||
|
kvfree(old);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int update_memcg_params(struct kmem_cache *s, int new_array_size)
|
static int update_memcg_params(struct kmem_cache *s, int new_array_size)
|
||||||
{
|
{
|
||||||
struct memcg_cache_array *old, *new;
|
struct memcg_cache_array *old, *new;
|
||||||
|
|
||||||
new = kzalloc(sizeof(struct memcg_cache_array) +
|
new = kvzalloc(sizeof(struct memcg_cache_array) +
|
||||||
new_array_size * sizeof(void *), GFP_KERNEL);
|
new_array_size * sizeof(void *), GFP_KERNEL);
|
||||||
if (!new)
|
if (!new)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
@ -198,7 +206,7 @@ static int update_memcg_params(struct kmem_cache *s, int new_array_size)
|
||||||
|
|
||||||
rcu_assign_pointer(s->memcg_params.memcg_caches, new);
|
rcu_assign_pointer(s->memcg_params.memcg_caches, new);
|
||||||
if (old)
|
if (old)
|
||||||
kfree_rcu(old, rcu);
|
call_rcu(&old->rcu, free_memcg_params);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -575,7 +575,7 @@ static void lru_lazyfree_fn(struct page *page, struct lruvec *lruvec,
|
||||||
void *arg)
|
void *arg)
|
||||||
{
|
{
|
||||||
if (PageLRU(page) && PageAnon(page) && PageSwapBacked(page) &&
|
if (PageLRU(page) && PageAnon(page) && PageSwapBacked(page) &&
|
||||||
!PageUnevictable(page)) {
|
!PageSwapCache(page) && !PageUnevictable(page)) {
|
||||||
bool active = PageActive(page);
|
bool active = PageActive(page);
|
||||||
|
|
||||||
del_page_from_lru_list(page, lruvec,
|
del_page_from_lru_list(page, lruvec,
|
||||||
|
@ -665,7 +665,7 @@ void deactivate_file_page(struct page *page)
|
||||||
void mark_page_lazyfree(struct page *page)
|
void mark_page_lazyfree(struct page *page)
|
||||||
{
|
{
|
||||||
if (PageLRU(page) && PageAnon(page) && PageSwapBacked(page) &&
|
if (PageLRU(page) && PageAnon(page) && PageSwapBacked(page) &&
|
||||||
!PageUnevictable(page)) {
|
!PageSwapCache(page) && !PageUnevictable(page)) {
|
||||||
struct pagevec *pvec = &get_cpu_var(lru_lazyfree_pvecs);
|
struct pagevec *pvec = &get_cpu_var(lru_lazyfree_pvecs);
|
||||||
|
|
||||||
get_page(page);
|
get_page(page);
|
||||||
|
|
|
@ -242,6 +242,17 @@ int add_to_swap(struct page *page)
|
||||||
* clear SWAP_HAS_CACHE flag.
|
* clear SWAP_HAS_CACHE flag.
|
||||||
*/
|
*/
|
||||||
goto fail;
|
goto fail;
|
||||||
|
/*
|
||||||
|
* Normally the page will be dirtied in unmap because its pte should be
|
||||||
|
* dirty. A special case is MADV_FREE page. The page'e pte could have
|
||||||
|
* dirty bit cleared but the page's SwapBacked bit is still set because
|
||||||
|
* clearing the dirty bit and SwapBacked bit has no lock protected. For
|
||||||
|
* such page, unmap will not set dirty bit for it, so page reclaim will
|
||||||
|
* not write the page out. This can cause data corruption when the page
|
||||||
|
* is swap in later. Always setting the dirty bit for the page solves
|
||||||
|
* the problem.
|
||||||
|
*/
|
||||||
|
set_page_dirty(page);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
|
10
mm/z3fold.c
10
mm/z3fold.c
|
@ -250,6 +250,7 @@ static void __release_z3fold_page(struct z3fold_header *zhdr, bool locked)
|
||||||
|
|
||||||
WARN_ON(!list_empty(&zhdr->buddy));
|
WARN_ON(!list_empty(&zhdr->buddy));
|
||||||
set_bit(PAGE_STALE, &page->private);
|
set_bit(PAGE_STALE, &page->private);
|
||||||
|
clear_bit(NEEDS_COMPACTING, &page->private);
|
||||||
spin_lock(&pool->lock);
|
spin_lock(&pool->lock);
|
||||||
if (!list_empty(&page->lru))
|
if (!list_empty(&page->lru))
|
||||||
list_del(&page->lru);
|
list_del(&page->lru);
|
||||||
|
@ -303,7 +304,6 @@ static void free_pages_work(struct work_struct *w)
|
||||||
list_del(&zhdr->buddy);
|
list_del(&zhdr->buddy);
|
||||||
if (WARN_ON(!test_bit(PAGE_STALE, &page->private)))
|
if (WARN_ON(!test_bit(PAGE_STALE, &page->private)))
|
||||||
continue;
|
continue;
|
||||||
clear_bit(NEEDS_COMPACTING, &page->private);
|
|
||||||
spin_unlock(&pool->stale_lock);
|
spin_unlock(&pool->stale_lock);
|
||||||
cancel_work_sync(&zhdr->work);
|
cancel_work_sync(&zhdr->work);
|
||||||
free_z3fold_page(page);
|
free_z3fold_page(page);
|
||||||
|
@ -624,10 +624,8 @@ lookup:
|
||||||
* stale pages list. cancel_work_sync() can sleep so we must make
|
* stale pages list. cancel_work_sync() can sleep so we must make
|
||||||
* sure it won't be called in case we're in atomic context.
|
* sure it won't be called in case we're in atomic context.
|
||||||
*/
|
*/
|
||||||
if (zhdr && (can_sleep || !work_pending(&zhdr->work) ||
|
if (zhdr && (can_sleep || !work_pending(&zhdr->work))) {
|
||||||
!unlikely(work_busy(&zhdr->work)))) {
|
|
||||||
list_del(&zhdr->buddy);
|
list_del(&zhdr->buddy);
|
||||||
clear_bit(NEEDS_COMPACTING, &page->private);
|
|
||||||
spin_unlock(&pool->stale_lock);
|
spin_unlock(&pool->stale_lock);
|
||||||
if (can_sleep)
|
if (can_sleep)
|
||||||
cancel_work_sync(&zhdr->work);
|
cancel_work_sync(&zhdr->work);
|
||||||
|
@ -875,16 +873,18 @@ static int z3fold_reclaim_page(struct z3fold_pool *pool, unsigned int retries)
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
next:
|
next:
|
||||||
|
spin_lock(&pool->lock);
|
||||||
if (test_bit(PAGE_HEADLESS, &page->private)) {
|
if (test_bit(PAGE_HEADLESS, &page->private)) {
|
||||||
if (ret == 0) {
|
if (ret == 0) {
|
||||||
|
spin_unlock(&pool->lock);
|
||||||
free_z3fold_page(page);
|
free_z3fold_page(page);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
} else if (kref_put(&zhdr->refcount, release_z3fold_page)) {
|
} else if (kref_put(&zhdr->refcount, release_z3fold_page)) {
|
||||||
atomic64_dec(&pool->pages_nr);
|
atomic64_dec(&pool->pages_nr);
|
||||||
|
spin_unlock(&pool->lock);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
spin_lock(&pool->lock);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Add to the beginning of LRU.
|
* Add to the beginning of LRU.
|
||||||
|
|
|
@ -6390,7 +6390,7 @@ sub process {
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$is_patch && $file !~ /cover-letter\.patch$/) {
|
if (!$is_patch && $filename !~ /cover-letter\.patch$/) {
|
||||||
ERROR("NOT_UNIFIED_DIFF",
|
ERROR("NOT_UNIFIED_DIFF",
|
||||||
"Does not appear to be a unified-diff format patch\n");
|
"Does not appear to be a unified-diff format patch\n");
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,6 +53,7 @@ acumulator||accumulator
|
||||||
adapater||adapter
|
adapater||adapter
|
||||||
addional||additional
|
addional||additional
|
||||||
additionaly||additionally
|
additionaly||additionally
|
||||||
|
additonal||additional
|
||||||
addres||address
|
addres||address
|
||||||
adddress||address
|
adddress||address
|
||||||
addreses||addresses
|
addreses||addresses
|
||||||
|
@ -67,6 +68,8 @@ adviced||advised
|
||||||
afecting||affecting
|
afecting||affecting
|
||||||
againt||against
|
againt||against
|
||||||
agaist||against
|
agaist||against
|
||||||
|
aggreataon||aggregation
|
||||||
|
aggreation||aggregation
|
||||||
albumns||albums
|
albumns||albums
|
||||||
alegorical||allegorical
|
alegorical||allegorical
|
||||||
algined||aligned
|
algined||aligned
|
||||||
|
@ -80,6 +83,8 @@ aligment||alignment
|
||||||
alignement||alignment
|
alignement||alignment
|
||||||
allign||align
|
allign||align
|
||||||
alligned||aligned
|
alligned||aligned
|
||||||
|
alllocate||allocate
|
||||||
|
alloated||allocated
|
||||||
allocatote||allocate
|
allocatote||allocate
|
||||||
allocatrd||allocated
|
allocatrd||allocated
|
||||||
allocte||allocate
|
allocte||allocate
|
||||||
|
@ -171,6 +176,7 @@ availale||available
|
||||||
availavility||availability
|
availavility||availability
|
||||||
availble||available
|
availble||available
|
||||||
availiable||available
|
availiable||available
|
||||||
|
availible||available
|
||||||
avalable||available
|
avalable||available
|
||||||
avaliable||available
|
avaliable||available
|
||||||
aysnc||async
|
aysnc||async
|
||||||
|
@ -203,6 +209,7 @@ broadcat||broadcast
|
||||||
cacluated||calculated
|
cacluated||calculated
|
||||||
caculation||calculation
|
caculation||calculation
|
||||||
calender||calendar
|
calender||calendar
|
||||||
|
calescing||coalescing
|
||||||
calle||called
|
calle||called
|
||||||
callibration||calibration
|
callibration||calibration
|
||||||
calucate||calculate
|
calucate||calculate
|
||||||
|
@ -210,6 +217,7 @@ calulate||calculate
|
||||||
cancelation||cancellation
|
cancelation||cancellation
|
||||||
cancle||cancel
|
cancle||cancel
|
||||||
capabilites||capabilities
|
capabilites||capabilities
|
||||||
|
capabilty||capability
|
||||||
capabitilies||capabilities
|
capabitilies||capabilities
|
||||||
capatibilities||capabilities
|
capatibilities||capabilities
|
||||||
capapbilities||capabilities
|
capapbilities||capabilities
|
||||||
|
@ -302,6 +310,7 @@ containts||contains
|
||||||
contaisn||contains
|
contaisn||contains
|
||||||
contant||contact
|
contant||contact
|
||||||
contence||contents
|
contence||contents
|
||||||
|
continious||continuous
|
||||||
continous||continuous
|
continous||continuous
|
||||||
continously||continuously
|
continously||continuously
|
||||||
continueing||continuing
|
continueing||continuing
|
||||||
|
@ -393,6 +402,7 @@ differrence||difference
|
||||||
diffrent||different
|
diffrent||different
|
||||||
diffrentiate||differentiate
|
diffrentiate||differentiate
|
||||||
difinition||definition
|
difinition||definition
|
||||||
|
dimesions||dimensions
|
||||||
diplay||display
|
diplay||display
|
||||||
direectly||directly
|
direectly||directly
|
||||||
disassocation||disassociation
|
disassocation||disassociation
|
||||||
|
@ -449,6 +459,7 @@ equiped||equipped
|
||||||
equivelant||equivalent
|
equivelant||equivalent
|
||||||
equivilant||equivalent
|
equivilant||equivalent
|
||||||
eror||error
|
eror||error
|
||||||
|
errorr||error
|
||||||
estbalishment||establishment
|
estbalishment||establishment
|
||||||
etsablishment||establishment
|
etsablishment||establishment
|
||||||
etsbalishment||establishment
|
etsbalishment||establishment
|
||||||
|
@ -481,6 +492,7 @@ failied||failed
|
||||||
faillure||failure
|
faillure||failure
|
||||||
failue||failure
|
failue||failure
|
||||||
failuer||failure
|
failuer||failure
|
||||||
|
failng||failing
|
||||||
faireness||fairness
|
faireness||fairness
|
||||||
falied||failed
|
falied||failed
|
||||||
faliure||failure
|
faliure||failure
|
||||||
|
@ -493,6 +505,7 @@ fetaure||feature
|
||||||
fetaures||features
|
fetaures||features
|
||||||
fileystem||filesystem
|
fileystem||filesystem
|
||||||
fimware||firmware
|
fimware||firmware
|
||||||
|
firware||firmware
|
||||||
finanize||finalize
|
finanize||finalize
|
||||||
findn||find
|
findn||find
|
||||||
finilizes||finalizes
|
finilizes||finalizes
|
||||||
|
@ -502,6 +515,7 @@ folloing||following
|
||||||
followign||following
|
followign||following
|
||||||
followings||following
|
followings||following
|
||||||
follwing||following
|
follwing||following
|
||||||
|
fonud||found
|
||||||
forseeable||foreseeable
|
forseeable||foreseeable
|
||||||
forse||force
|
forse||force
|
||||||
fortan||fortran
|
fortan||fortran
|
||||||
|
@ -532,6 +546,7 @@ grabing||grabbing
|
||||||
grahical||graphical
|
grahical||graphical
|
||||||
grahpical||graphical
|
grahpical||graphical
|
||||||
grapic||graphic
|
grapic||graphic
|
||||||
|
grranted||granted
|
||||||
guage||gauge
|
guage||gauge
|
||||||
guarenteed||guaranteed
|
guarenteed||guaranteed
|
||||||
guarentee||guarantee
|
guarentee||guarantee
|
||||||
|
@ -543,6 +558,7 @@ happend||happened
|
||||||
harware||hardware
|
harware||hardware
|
||||||
heirarchically||hierarchically
|
heirarchically||hierarchically
|
||||||
helpfull||helpful
|
helpfull||helpful
|
||||||
|
hybernate||hibernate
|
||||||
hierachy||hierarchy
|
hierachy||hierarchy
|
||||||
hierarchie||hierarchy
|
hierarchie||hierarchy
|
||||||
howver||however
|
howver||however
|
||||||
|
@ -565,16 +581,19 @@ implemenation||implementation
|
||||||
implementaiton||implementation
|
implementaiton||implementation
|
||||||
implementated||implemented
|
implementated||implemented
|
||||||
implemention||implementation
|
implemention||implementation
|
||||||
|
implementd||implemented
|
||||||
implemetation||implementation
|
implemetation||implementation
|
||||||
implemntation||implementation
|
implemntation||implementation
|
||||||
implentation||implementation
|
implentation||implementation
|
||||||
implmentation||implementation
|
implmentation||implementation
|
||||||
implmenting||implementing
|
implmenting||implementing
|
||||||
|
incative||inactive
|
||||||
incomming||incoming
|
incomming||incoming
|
||||||
incompatabilities||incompatibilities
|
incompatabilities||incompatibilities
|
||||||
incompatable||incompatible
|
incompatable||incompatible
|
||||||
inconsistant||inconsistent
|
inconsistant||inconsistent
|
||||||
increas||increase
|
increas||increase
|
||||||
|
incremeted||incremented
|
||||||
incrment||increment
|
incrment||increment
|
||||||
indendation||indentation
|
indendation||indentation
|
||||||
indended||intended
|
indended||intended
|
||||||
|
@ -619,6 +638,7 @@ interger||integer
|
||||||
intermittant||intermittent
|
intermittant||intermittent
|
||||||
internel||internal
|
internel||internal
|
||||||
interoprability||interoperability
|
interoprability||interoperability
|
||||||
|
interuupt||interrupt
|
||||||
interrface||interface
|
interrface||interface
|
||||||
interrrupt||interrupt
|
interrrupt||interrupt
|
||||||
interrup||interrupt
|
interrup||interrupt
|
||||||
|
@ -638,8 +658,10 @@ intrrupt||interrupt
|
||||||
intterrupt||interrupt
|
intterrupt||interrupt
|
||||||
intuative||intuitive
|
intuative||intuitive
|
||||||
invaid||invalid
|
invaid||invalid
|
||||||
|
invald||invalid
|
||||||
invalde||invalid
|
invalde||invalid
|
||||||
invalide||invalid
|
invalide||invalid
|
||||||
|
invalidiate||invalidate
|
||||||
invalud||invalid
|
invalud||invalid
|
||||||
invididual||individual
|
invididual||individual
|
||||||
invokation||invocation
|
invokation||invocation
|
||||||
|
@ -713,6 +735,7 @@ misformed||malformed
|
||||||
mispelled||misspelled
|
mispelled||misspelled
|
||||||
mispelt||misspelt
|
mispelt||misspelt
|
||||||
mising||missing
|
mising||missing
|
||||||
|
mismactch||mismatch
|
||||||
missmanaged||mismanaged
|
missmanaged||mismanaged
|
||||||
missmatch||mismatch
|
missmatch||mismatch
|
||||||
miximum||maximum
|
miximum||maximum
|
||||||
|
@ -731,6 +754,7 @@ multidimensionnal||multidimensional
|
||||||
multple||multiple
|
multple||multiple
|
||||||
mumber||number
|
mumber||number
|
||||||
muticast||multicast
|
muticast||multicast
|
||||||
|
mutilcast||multicast
|
||||||
mutiple||multiple
|
mutiple||multiple
|
||||||
mutli||multi
|
mutli||multi
|
||||||
nams||names
|
nams||names
|
||||||
|
@ -834,6 +858,7 @@ posible||possible
|
||||||
positon||position
|
positon||position
|
||||||
possibilites||possibilities
|
possibilites||possibilities
|
||||||
powerfull||powerful
|
powerfull||powerful
|
||||||
|
preample||preamble
|
||||||
preapre||prepare
|
preapre||prepare
|
||||||
preceeded||preceded
|
preceeded||preceded
|
||||||
preceeding||preceding
|
preceeding||preceding
|
||||||
|
@ -1059,6 +1084,7 @@ sturcture||structure
|
||||||
subdirectoires||subdirectories
|
subdirectoires||subdirectories
|
||||||
suble||subtle
|
suble||subtle
|
||||||
substract||subtract
|
substract||subtract
|
||||||
|
submition||submission
|
||||||
succesfully||successfully
|
succesfully||successfully
|
||||||
succesful||successful
|
succesful||successful
|
||||||
successed||succeeded
|
successed||succeeded
|
||||||
|
@ -1078,6 +1104,7 @@ suppoted||supported
|
||||||
suppported||supported
|
suppported||supported
|
||||||
suppport||support
|
suppport||support
|
||||||
supress||suppress
|
supress||suppress
|
||||||
|
surpressed||suppressed
|
||||||
surpresses||suppresses
|
surpresses||suppresses
|
||||||
susbsystem||subsystem
|
susbsystem||subsystem
|
||||||
suspeneded||suspended
|
suspeneded||suspended
|
||||||
|
@ -1091,6 +1118,7 @@ swithced||switched
|
||||||
swithcing||switching
|
swithcing||switching
|
||||||
swithed||switched
|
swithed||switched
|
||||||
swithing||switching
|
swithing||switching
|
||||||
|
swtich||switch
|
||||||
symetric||symmetric
|
symetric||symmetric
|
||||||
synax||syntax
|
synax||syntax
|
||||||
synchonized||synchronized
|
synchonized||synchronized
|
||||||
|
@ -1111,7 +1139,9 @@ therfore||therefore
|
||||||
thier||their
|
thier||their
|
||||||
threds||threads
|
threds||threads
|
||||||
threshhold||threshold
|
threshhold||threshold
|
||||||
|
thresold||threshold
|
||||||
throught||through
|
throught||through
|
||||||
|
troughput||throughput
|
||||||
thses||these
|
thses||these
|
||||||
tiggered||triggered
|
tiggered||triggered
|
||||||
tipically||typically
|
tipically||typically
|
||||||
|
@ -1120,6 +1150,7 @@ tmis||this
|
||||||
torerable||tolerable
|
torerable||tolerable
|
||||||
tramsmitted||transmitted
|
tramsmitted||transmitted
|
||||||
tramsmit||transmit
|
tramsmit||transmit
|
||||||
|
tranasction||transaction
|
||||||
tranfer||transfer
|
tranfer||transfer
|
||||||
transciever||transceiver
|
transciever||transceiver
|
||||||
transferd||transferred
|
transferd||transferred
|
||||||
|
@ -1133,6 +1164,7 @@ trasmission||transmission
|
||||||
treshold||threshold
|
treshold||threshold
|
||||||
trigerring||triggering
|
trigerring||triggering
|
||||||
trun||turn
|
trun||turn
|
||||||
|
tunning||tuning
|
||||||
ture||true
|
ture||true
|
||||||
tyep||type
|
tyep||type
|
||||||
udpate||update
|
udpate||update
|
||||||
|
@ -1199,6 +1231,7 @@ visiters||visitors
|
||||||
vitual||virtual
|
vitual||virtual
|
||||||
wakeus||wakeups
|
wakeus||wakeups
|
||||||
wating||waiting
|
wating||waiting
|
||||||
|
wiat||wait
|
||||||
wether||whether
|
wether||whether
|
||||||
whataver||whatever
|
whataver||whatever
|
||||||
whcih||which
|
whcih||which
|
||||||
|
|
Loading…
Reference in New Issue