Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F108247992
D24942.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
2 KB
Referenced Files
None
Subscribers
None
D24942.diff
View Options
Index: head/sys/compat/linuxkpi/common/include/linux/workqueue.h
===================================================================
--- head/sys/compat/linuxkpi/common/include/linux/workqueue.h
+++ head/sys/compat/linuxkpi/common/include/linux/workqueue.h
@@ -72,6 +72,13 @@
atomic_t state;
};
+struct rcu_work {
+ struct work_struct work;
+ struct rcu_head rcu;
+
+ struct workqueue_struct *wq;
+};
+
#define DECLARE_WORK(name, fn) \
struct work_struct name; \
static void name##_init(void *arg) \
@@ -112,6 +119,9 @@
TASK_INIT(&(work)->work_task, 0, linux_work_fn, (work)); \
} while (0)
+#define INIT_RCU_WORK(_work, _fn) \
+ INIT_WORK(&(_work)->work, (_fn))
+
#define INIT_WORK_ONSTACK(work, fn) \
INIT_WORK(work, fn)
@@ -192,6 +202,12 @@
#define flush_work(work) \
linux_flush_work(work)
+#define queue_rcu_work(wq, rwork) \
+ linux_queue_rcu_work(wq, rwork)
+
+#define flush_rcu_work(rwork) \
+ linux_flush_rcu_work(rwork)
+
#define flush_delayed_work(dwork) \
linux_flush_delayed_work(dwork)
@@ -237,5 +253,7 @@
extern bool linux_work_pending(struct work_struct *);
extern bool linux_work_busy(struct work_struct *);
extern struct work_struct *linux_current_work(void);
+extern bool linux_queue_rcu_work(struct workqueue_struct *wq, struct rcu_work *rwork);
+extern bool linux_flush_rcu_work(struct rcu_work *rwork);
#endif /* _LINUX_WORKQUEUE_H_ */
Index: head/sys/compat/linuxkpi/common/src/linux_work.c
===================================================================
--- head/sys/compat/linuxkpi/common/src/linux_work.c
+++ head/sys/compat/linuxkpi/common/src/linux_work.c
@@ -31,6 +31,7 @@
#include <linux/wait.h>
#include <linux/compat.h>
#include <linux/spinlock.h>
+#include <linux/rcupdate.h>
#include <sys/kernel.h>
@@ -153,6 +154,53 @@
default:
return (false); /* already on a queue */
}
+}
+
+/*
+ * Callback func for linux_queue_rcu_work
+ */
+static void
+rcu_work_func(struct rcu_head *rcu)
+{
+ struct rcu_work *rwork;
+
+ rwork = container_of(rcu, struct rcu_work, rcu);
+ linux_queue_work_on(WORK_CPU_UNBOUND, rwork->wq, &rwork->work);
+}
+
+/*
+ * This function queue a work after a grace period
+ * If the work was already pending it returns false,
+ * if not it calls call_rcu and returns true.
+ */
+bool
+linux_queue_rcu_work(struct workqueue_struct *wq, struct rcu_work *rwork)
+{
+
+ if (!linux_work_pending(&rwork->work)) {
+ rwork->wq = wq;
+ linux_call_rcu(RCU_TYPE_REGULAR, &rwork->rcu, rcu_work_func);
+ return (true);
+ }
+ return (false);
+}
+
+/*
+ * This function waits for the last execution of a work and then
+ * flush the work.
+ * It returns true if the work was pending and we waited, it returns
+ * false otherwise.
+ */
+bool
+linux_flush_rcu_work(struct rcu_work *rwork)
+{
+
+ if (linux_work_pending(&rwork->work)) {
+ linux_rcu_barrier(RCU_TYPE_REGULAR);
+ linux_flush_work(&rwork->work);
+ return (true);
+ }
+ return (linux_flush_work(&rwork->work));
}
/*
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Jan 24, 2:24 AM (21 h, 17 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16071846
Default Alt Text
D24942.diff (2 KB)
Attached To
Mode
D24942: linuxkpi: Add rcu_work functions.
Attached
Detach File
Event Timeline
Log In to Comment