anolis: pstore: replace might_sleep rcu_read_lock with mutex

ANBZ: #4274

Pstore currently use rcu_read_lock and would result
in might_sleep. Replace rcu_read_lock with mutex when
there is no might_sleep in context.

Signed-off-by: Yuanhe Shu <xiangzao@linux.alibaba.com>
Reviewed-by: Xunlei Pang <xlpang@linux.alibaba.com>
Link: https://gitee.com/anolis/cloud-kernel/pulls/1452
This commit is contained in:
Yuanhe Shu 2023-03-13 23:58:16 +08:00 committed by 小龙
parent b549959d6a
commit deca542a06
5 changed files with 23 additions and 27 deletions

View File

@ -510,12 +510,12 @@ static int pstore_fill_super(struct super_block *sb, void *data, int silent)
pstore_sb = sb;
mutex_unlock(&pstore_sb_lock);
rcu_read_lock();
list_for_each_entry_rcu(entry, &psback->list_entry, list) {
mutex_lock(&psback_lock);
list_for_each_entry(entry, &psback->list_entry, list) {
pstore_mksubdir(entry->psi);
pstore_get_records(entry->psi, entry->index, 0);
}
rcu_read_unlock();
mutex_unlock(&psback_lock);
psback->fs_ready = true;

View File

@ -74,7 +74,7 @@ static DECLARE_WORK(pstore_work, pstore_dowork);
* pstore_register(), pstore_unregister(), and
* the filesystem mount/unmount routines.
*/
static DEFINE_MUTEX(psback_lock);
DEFINE_MUTEX(psback_lock);
struct pstore_backends *psback;
static char *compress =
@ -605,15 +605,13 @@ int pstore_register(struct pstore_info *psi)
mutex_unlock(&psback_lock);
return -EBUSY;
}
rcu_read_lock();
list_for_each_entry_rcu(entry, &psback->list_entry, list) {
list_for_each_entry(entry, &psback->list_entry, list) {
if (strcmp(entry->psi->name, psi->name) == 0) {
pr_warn("ignoring unexpected backend '%s'\n", psi->name);
mutex_unlock(&psback_lock);
return -EPERM;
}
}
rcu_read_unlock();
}
if (!psback) {
@ -629,7 +627,6 @@ int pstore_register(struct pstore_info *psi)
pslist->psi = psi;
pslist->index = ffz(psback->flag);
INIT_LIST_HEAD(&pslist->list);
list_add_rcu(&pslist->list, &psback->list_entry);
psback->flag |= (1 << pslist->index);
mutex_init(&psi->read_mutex);
@ -659,6 +656,8 @@ int pstore_register(struct pstore_info *psi)
/* Start watching for new records, if desired. */
pstore_timer_kick();
list_add_rcu(&pslist->list, &psback->list_entry);
pr_info("Registered %s as persistent store backend\n", psi->name);
mutex_unlock(&psback_lock);
@ -694,17 +693,16 @@ void pstore_unregister(struct pstore_info *psi)
/* Remove all backend records from filesystem tree. */
pstore_put_backend_records(psi);
rcu_read_lock();
list_for_each_entry_rcu(entry, &psback->list_entry, list) {
list_for_each_entry(entry, &psback->list_entry, list) {
if (entry->psi == psi) {
free_buf_for_compression(entry->index);
list_del_rcu(&entry->list);
psback->flag ^= 1 << entry->index;
synchronize_rcu();
free_buf_for_compression(entry->index);
kfree(entry);
break;
}
}
rcu_read_unlock();
if (psback->flag == PSOTRE_LIST_EMPTY) {
kfree(psback);
@ -840,10 +838,10 @@ static void pstore_dowork(struct work_struct *work)
{
struct pstore_info_list *entry;
rcu_read_lock();
list_for_each_entry_rcu(entry, &psback->list_entry, list)
mutex_lock(&psback_lock);
list_for_each_entry(entry, &psback->list_entry, list)
pstore_get_records(entry->psi, entry->index, 1);
rcu_read_unlock();
mutex_unlock(&psback_lock);
}
static void pstore_timefunc(struct timer_list *unused)
@ -886,18 +884,18 @@ static int __init pstore_init(void)
* initialize compression because crypto was not ready. If so,
* initialize compression now.
*/
rcu_read_lock();
list_for_each_entry_rcu(entry, &psback->list_entry, list)
mutex_lock(&psback_lock);
list_for_each_entry(entry, &psback->list_entry, list)
allocate_buf_for_compression(entry->psi, entry->index);
rcu_read_unlock();
mutex_unlock(&psback_lock);
ret = pstore_init_fs();
if (ret) {
rcu_read_lock();
list_for_each_entry_rcu(entry, &psback->list_entry, list)
mutex_lock(&psback_lock);
list_for_each_entry(entry, &psback->list_entry, list)
free_buf_for_compression(entry->index);
rcu_read_unlock();
mutex_unlock(&psback_lock);
}
return ret;

View File

@ -40,15 +40,15 @@ static ssize_t write_pmsg(struct file *file, const char __user *buf,
int ret;
struct pstore_info_list *entry;
rcu_read_lock();
list_for_each_entry_rcu(entry, &psback->list_entry, list) {
mutex_lock(&psback_lock);
list_for_each_entry(entry, &psback->list_entry, list) {
if (entry->psi->flags & PSTORE_FLAGS_PMSG) {
int _ret = do_write_pmsg(file, buf, count, ppos, entry->psi);
ret = ret > _ret ? ret : _ret;
}
}
rcu_read_unlock();
mutex_unlock(&psback_lock);
return ret;
}

View File

@ -13,7 +13,6 @@
#include <linux/tty_driver.h>
#include "internal.h"
static DEFINE_MUTEX(ttymsg_lock);
DEFINE_STATIC_KEY_FALSE(ttyprobe_key);
#define TTYPROBE_NAME "ttyprobe"
@ -36,10 +35,8 @@ static void do_write_ttymsg(const unsigned char *buf, int count,
newline.size = strlen(lbreak);
newline.buf = lbreak;
mutex_lock(&ttymsg_lock);
psinfo->write(&record);
psinfo->write(&newline);
mutex_unlock(&ttymsg_lock);
}
void pstore_register_ttyprobe(void)

View File

@ -236,6 +236,7 @@ struct pstore_backends {
extern int pstore_register(struct pstore_info *);
extern void pstore_unregister(struct pstore_info *);
extern struct mutex psback_lock;
struct pstore_ftrace_record {
unsigned long ip;