summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/linux/liveupdate.h1
-rw-r--r--kernel/liveupdate/luo_flb.c14
2 files changed, 15 insertions, 0 deletions
diff --git a/include/linux/liveupdate.h b/include/linux/liveupdate.h
index 61325ad26526..9c761d9bacf8 100644
--- a/include/linux/liveupdate.h
+++ b/include/linux/liveupdate.h
@@ -12,6 +12,7 @@
#include <linux/kho/abi/luo.h>
#include <linux/list.h>
#include <linux/mutex.h>
+#include <linux/rwsem.h>
#include <linux/types.h>
#include <uapi/linux/liveupdate.h>
diff --git a/kernel/liveupdate/luo_flb.c b/kernel/liveupdate/luo_flb.c
index cf4a8f854c83..fdb274410e8f 100644
--- a/kernel/liveupdate/luo_flb.c
+++ b/kernel/liveupdate/luo_flb.c
@@ -245,17 +245,20 @@ int luo_flb_file_preserve(struct liveupdate_file_handler *fh)
struct luo_flb_link *iter;
int err = 0;
+ down_read(&luo_register_rwlock);
list_for_each_entry(iter, flb_list, list) {
err = luo_flb_file_preserve_one(iter->flb);
if (err)
goto exit_err;
}
+ up_read(&luo_register_rwlock);
return 0;
exit_err:
list_for_each_entry_continue_reverse(iter, flb_list, list)
luo_flb_file_unpreserve_one(iter->flb);
+ up_read(&luo_register_rwlock);
return err;
}
@@ -277,6 +280,7 @@ void luo_flb_file_unpreserve(struct liveupdate_file_handler *fh)
struct list_head *flb_list = &ACCESS_PRIVATE(fh, flb_list);
struct luo_flb_link *iter;
+ guard(rwsem_read)(&luo_register_rwlock);
list_for_each_entry_reverse(iter, flb_list, list)
luo_flb_file_unpreserve_one(iter->flb);
}
@@ -297,6 +301,7 @@ void luo_flb_file_finish(struct liveupdate_file_handler *fh)
struct list_head *flb_list = &ACCESS_PRIVATE(fh, flb_list);
struct luo_flb_link *iter;
+ guard(rwsem_read)(&luo_register_rwlock);
list_for_each_entry_reverse(iter, flb_list, list)
luo_flb_file_finish_one(iter->flb);
}
@@ -360,6 +365,8 @@ int liveupdate_register_flb(struct liveupdate_file_handler *fh,
if (!luo_session_quiesce())
return -EBUSY;
+ down_write(&luo_register_rwlock);
+
/* Check that this FLB is not already linked to this file handler */
err = -EEXIST;
list_for_each_entry(iter, flb_list, list) {
@@ -401,11 +408,13 @@ int liveupdate_register_flb(struct liveupdate_file_handler *fh,
private->users++;
link->flb = flb;
list_add_tail(&no_free_ptr(link)->list, flb_list);
+ up_write(&luo_register_rwlock);
luo_session_resume();
return 0;
err_resume:
+ up_write(&luo_register_rwlock);
luo_session_resume();
return err;
}
@@ -449,6 +458,8 @@ int liveupdate_unregister_flb(struct liveupdate_file_handler *fh,
if (!luo_session_quiesce())
return -EBUSY;
+ down_write(&luo_register_rwlock);
+
/* Find and remove the link from the file handler's list */
list_for_each_entry(iter, flb_list, list) {
if (iter->flb == flb) {
@@ -473,11 +484,13 @@ int liveupdate_unregister_flb(struct liveupdate_file_handler *fh,
module_put(flb->ops->owner);
}
+ up_write(&luo_register_rwlock);
luo_session_resume();
return 0;
err_resume:
+ up_write(&luo_register_rwlock);
luo_session_resume();
return err;
}
@@ -643,6 +656,7 @@ void luo_flb_serialize(void)
struct liveupdate_flb *gflb;
int i = 0;
+ guard(rwsem_read)(&luo_register_rwlock);
list_private_for_each_entry(gflb, &luo_flb_global.list, private.list) {
struct luo_flb_private *private = luo_flb_get_private(gflb);