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
1515
1616 struct srcu_struct {
1717 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. */
1919 u8 srcu_gp_running; /* GP workqueue running? */
2020 u8 srcu_gp_waiting; /* GP waiting for readers? */
2121 struct swait_queue_head srcu_wq;
@@ -59,7 +59,7 @@ static inline int __srcu_read_lock(struct srcu_struct *ssp) · 37 unmodified lines
5959 {
6060 int idx;
6161
62− idx = READ_ONCE(ssp->srcu_idx);
62+ idx = ((READ_ONCE(ssp->srcu_idx) + 1) & 0x2) >> 1;
6363 WRITE_ONCE(ssp->srcu_lock_nesting[idx], ssp->srcu_lock_nesting[idx] + 1);
6464 return idx;
6565 }
@@ -80,7 +80,7 @@ static inline void srcu_torture_stats_print(struct srcu_struct *ssp, · 14 unmodified lines
8080 {
8181 int idx;
8282
83− idx = READ_ONCE(ssp->srcu_idx) & 0x1;
83+ idx = ((READ_ONCE(ssp->srcu_idx) + 1) & 0x2) >> 1;
8484 pr_alert("%s%s Tiny SRCU per-CPU(idx=%d): (%hd,%hd)\n",
8585 tt, tf, idx,
8686 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
124124 ssp->srcu_cb_head = NULL;
125125 ssp->srcu_cb_tail = &ssp->srcu_cb_head;
126126 local_irq_enable();
127− idx = ssp->srcu_idx;
128− WRITE_ONCE(ssp->srcu_idx, !ssp->srcu_idx);
127+ idx = (ssp->srcu_idx & 0x2) / 2;
128+ WRITE_ONCE(ssp->srcu_idx, ssp->srcu_idx + 1);
129129 WRITE_ONCE(ssp->srcu_gp_waiting, true); /* srcu_read_unlock() wakes! */
130130 swait_event_exclusive(ssp->srcu_wq, !READ_ONCE(ssp->srcu_lock_nesting[idx]));
131131 WRITE_ONCE(ssp->srcu_gp_waiting, false); /* srcu_read_unlock() cheap. */
132+ WRITE_ONCE(ssp->srcu_idx, ssp->srcu_idx + 1);
132133
133134 /* Invoke the callbacks we removed above. */
134135 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