
hulk inclusion category: feature bugzilla: https://gitee.com/openeuler/kernel/issues/IC97W5 ---------------------------------------- Add input parameter 'limit' for inc_rlimit_[get_]ucounts[_limit] function. The 'limit' will be used for rlimit percpu_counter inplementation. No function changes now. Signed-off-by: Chen Ridong <chenridong@huawei.com> --- include/linux/user_namespace.h | 9 +++++++-- ipc/mqueue.c | 3 ++- kernel/signal.c | 2 +- kernel/ucount.c | 5 +++-- mm/mlock.c | 2 +- 5 files changed, 14 insertions(+), 7 deletions(-) diff --git a/include/linux/user_namespace.h b/include/linux/user_namespace.h index c3b4de67471c8..8ec4a694d1f2a 100644 --- a/include/linux/user_namespace.h +++ b/include/linux/user_namespace.h @@ -145,10 +145,15 @@ static inline long get_rlimit_value(struct ucounts *ucounts, enum rlimit_type ty return atomic_long_read(&ucounts->rlimit[type]); } -long inc_rlimit_ucounts(struct ucounts *ucounts, enum rlimit_type type, long v); +long inc_rlimit_ucounts_limit(struct ucounts *ucounts, enum rlimit_type type, long v, long limit); +static inline long inc_rlimit_ucounts(struct ucounts *ucounts, enum rlimit_type type, long v) +{ + return inc_rlimit_ucounts_limit(ucounts, type, v, LONG_MAX); +} + bool dec_rlimit_ucounts(struct ucounts *ucounts, enum rlimit_type type, long v); long inc_rlimit_get_ucounts(struct ucounts *ucounts, enum rlimit_type type, - bool override_rlimit); + bool override_rlimit, long limit); void dec_rlimit_put_ucounts(struct ucounts *ucounts, enum rlimit_type type); bool is_rlimit_overlimit(struct ucounts *ucounts, enum rlimit_type type, unsigned long max); diff --git a/ipc/mqueue.c b/ipc/mqueue.c index ba8215ed663a4..842b31196c127 100644 --- a/ipc/mqueue.c +++ b/ipc/mqueue.c @@ -374,7 +374,8 @@ static struct inode *mqueue_get_inode(struct super_block *sb, long msgqueue; spin_lock(&mq_lock); - msgqueue = inc_rlimit_ucounts(info->ucounts, UCOUNT_RLIMIT_MSGQUEUE, mq_bytes); + msgqueue = inc_rlimit_ucounts_limit(info->ucounts, UCOUNT_RLIMIT_MSGQUEUE, + mq_bytes, rlimit(RLIMIT_MSGQUEUE)); if (msgqueue == LONG_MAX || msgqueue > rlimit(RLIMIT_MSGQUEUE)) { dec_rlimit_ucounts(info->ucounts, UCOUNT_RLIMIT_MSGQUEUE, mq_bytes); spin_unlock(&mq_lock); diff --git a/kernel/signal.c b/kernel/signal.c index c73873d67a63f..fa8a04a7a578d 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -429,7 +429,7 @@ __sigqueue_alloc(int sig, struct task_struct *t, gfp_t gfp_flags, rcu_read_lock(); ucounts = task_ucounts(t); sigpending = inc_rlimit_get_ucounts(ucounts, UCOUNT_RLIMIT_SIGPENDING, - override_rlimit); + override_rlimit, task_rlimit(t, RLIMIT_SIGPENDING)); rcu_read_unlock(); if (!sigpending) return NULL; diff --git a/kernel/ucount.c b/kernel/ucount.c index fd2ccffe08394..778279318e1dd 100644 --- a/kernel/ucount.c +++ b/kernel/ucount.c @@ -251,7 +251,8 @@ void dec_ucount(struct ucounts *ucounts, enum ucount_type type) put_ucounts(ucounts); } -long inc_rlimit_ucounts(struct ucounts *ucounts, enum rlimit_type type, long v) +long inc_rlimit_ucounts_limit(struct ucounts *ucounts, enum rlimit_type type, + long v, long limit) { struct ucounts *iter; long max = LONG_MAX; @@ -300,7 +301,7 @@ void dec_rlimit_put_ucounts(struct ucounts *ucounts, enum rlimit_type type) } long inc_rlimit_get_ucounts(struct ucounts *ucounts, enum rlimit_type type, - bool override_rlimit) + bool override_rlimit, long limit) { /* Caller must hold a reference to ucounts */ struct ucounts *iter; diff --git a/mm/mlock.c b/mm/mlock.c index cd0997d89c7c5..f9653d30d0256 100644 --- a/mm/mlock.c +++ b/mm/mlock.c @@ -833,7 +833,7 @@ int user_shm_lock(size_t size, struct ucounts *ucounts) if (lock_limit != RLIM_INFINITY) lock_limit >>= PAGE_SHIFT; spin_lock(&shmlock_user_lock); - memlock = inc_rlimit_ucounts(ucounts, UCOUNT_RLIMIT_MEMLOCK, locked); + memlock = inc_rlimit_ucounts_limit(ucounts, UCOUNT_RLIMIT_MEMLOCK, locked, lock_limit); if ((memlock == LONG_MAX || memlock > lock_limit) && !capable(CAP_IPC_LOCK)) { dec_rlimit_ucounts(ucounts, UCOUNT_RLIMIT_MEMLOCK, locked); -- 2.34.1