History

srcu: Make Tiny SRCU use multi-bit grace-period counter

There is a need for a polling interface for SRCU grace periods. This polling needs to distinguish between an SRCU instance being idle on the one hand or in the middle of a grace period on the other. This commit therefore converts the Tiny SRCU srcu_struct structure's srcu_idx from a defacto boolean to a free-running counter, using the bottom bit to indicate that a grace period is in progress. The second-from-bottom bit is thus used as the index returned by srcu_read_lock().

Paul E. McKenney committed 6 years ago

Commit 74612a01 parent 5c8fe582 files · +6 −5Browse files

Unified · Split

2 files
  1. include/linux/srcutiny.h +3 −3
  2. kernel/rcu/srcutiny.c +3 −2
include/linux/srcutiny.h+3−3
@@ -15,7 +15,7 @@ · 14 unmodified lines
15 15
16struct srcu_struct {16struct srcu_struct {
17 short srcu_lock_nesting[2]; /* srcu_read_lock() nesting depth. */17 short srcu_lock_nesting[2]; /* srcu_read_lock() nesting depth. */
18 short srcu_idx; /* Current reader array element. */18 unsigned short srcu_idx; /* Current reader array element in bit 0x2. */
19 u8 srcu_gp_running; /* GP workqueue running? */19 u8 srcu_gp_running; /* GP workqueue running? */
20 u8 srcu_gp_waiting; /* GP waiting for readers? */20 u8 srcu_gp_waiting; /* GP waiting for readers? */
21 struct swait_queue_head srcu_wq;21 struct swait_queue_head srcu_wq;
@@ -59,7 +59,7 @@ static inline int __srcu_read_lock(struct srcu_struct *ssp) · 37 unmodified lines
59{59{
60 int idx;60 int idx;
61 61
62 idx = READ_ONCE(ssp->srcu_idx);62 idx = ((READ_ONCE(ssp->srcu_idx) + 1) & 0x2) >> 1;
63 WRITE_ONCE(ssp->srcu_lock_nesting[idx], ssp->srcu_lock_nesting[idx] + 1);63 WRITE_ONCE(ssp->srcu_lock_nesting[idx], ssp->srcu_lock_nesting[idx] + 1);
64 return idx;64 return idx;
65}65}
@@ -80,7 +80,7 @@ static inline void srcu_torture_stats_print(struct srcu_struct *ssp, · 14 unmodified lines
80{80{
81 int idx;81 int idx;
82 82
83 idx = READ_ONCE(ssp->srcu_idx) & 0x1;83 idx = ((READ_ONCE(ssp->srcu_idx) + 1) & 0x2) >> 1;
84 pr_alert("%s%s Tiny SRCU per-CPU(idx=%d): (%hd,%hd)\n",84 pr_alert("%s%s Tiny SRCU per-CPU(idx=%d): (%hd,%hd)\n",
85 tt, tf, idx,85 tt, tf, idx,
86 READ_ONCE(ssp->srcu_lock_nesting[!idx]),86 READ_ONCE(ssp->srcu_lock_nesting[!idx]),
kernel/rcu/srcutiny.c+3−2
@@ -124,11 +124,12 @@ void srcu_drive_gp(struct work_struct *wp) · 123 unmodified lines
124 ssp->srcu_cb_head = NULL;124 ssp->srcu_cb_head = NULL;
125 ssp->srcu_cb_tail = &ssp->srcu_cb_head;125 ssp->srcu_cb_tail = &ssp->srcu_cb_head;
126 local_irq_enable();126 local_irq_enable();
127 idx = ssp->srcu_idx;127 idx = (ssp->srcu_idx & 0x2) / 2;
128 WRITE_ONCE(ssp->srcu_idx, !ssp->srcu_idx);128 WRITE_ONCE(ssp->srcu_idx, ssp->srcu_idx + 1);
129 WRITE_ONCE(ssp->srcu_gp_waiting, true); /* srcu_read_unlock() wakes! */129 WRITE_ONCE(ssp->srcu_gp_waiting, true); /* srcu_read_unlock() wakes! */
130 swait_event_exclusive(ssp->srcu_wq, !READ_ONCE(ssp->srcu_lock_nesting[idx]));130 swait_event_exclusive(ssp->srcu_wq, !READ_ONCE(ssp->srcu_lock_nesting[idx]));
131 WRITE_ONCE(ssp->srcu_gp_waiting, false); /* srcu_read_unlock() cheap. */131 WRITE_ONCE(ssp->srcu_gp_waiting, false); /* srcu_read_unlock() cheap. */
132 WRITE_ONCE(ssp->srcu_idx, ssp->srcu_idx + 1);
132 133
133 /* Invoke the callbacks we removed above. */134 /* Invoke the callbacks we removed above. */
134 while (lh) {135 while (lh) {

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t