Skip to content

Commit 253cbbf

Browse files
committed
rcu: Throttle callback invocation based on number of ready callbacks
Currently, rcu_do_batch() sizes its batches based on the total number of callbacks in the callback list. This can result in some strange choices, for example, if there was 12,800 callbacks in the list, but only 200 were ready to invoke, RCU would invoke 100 at a time (12,800 shifted down by seven bits). A more measured approach would use the number that were actually ready to invoke, an approach that has become feasible only recently given the per-segment ->seglen counts in ->cblist. This commit therefore bases the batch limit on the number of callbacks ready to invoke instead of on the total number of callbacks. Signed-off-by: Paul E. McKenney <[email protected]>
1 parent 5a04848 commit 253cbbf

File tree

3 files changed

+4
-2
lines changed

3 files changed

+4
-2
lines changed

kernel/rcu/rcu_segcblist.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ static void rcu_segcblist_set_len(struct rcu_segcblist *rsclp, long v)
8989
}
9090

9191
/* Get the length of a segment of the rcu_segcblist structure. */
92-
static long rcu_segcblist_get_seglen(struct rcu_segcblist *rsclp, int seg)
92+
long rcu_segcblist_get_seglen(struct rcu_segcblist *rsclp, int seg)
9393
{
9494
return READ_ONCE(rsclp->seglen[seg]);
9595
}

kernel/rcu/rcu_segcblist.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ static inline long rcu_cblist_n_cbs(struct rcu_cblist *rclp)
1515
return READ_ONCE(rclp->len);
1616
}
1717

18+
long rcu_segcblist_get_seglen(struct rcu_segcblist *rsclp, int seg);
19+
1820
/* Return number of callbacks in segmented callback list by summing seglen. */
1921
long rcu_segcblist_n_segment_cbs(struct rcu_segcblist *rsclp);
2022

kernel/rcu/tree.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2057,7 +2057,7 @@ static void rcu_do_batch(struct rcu_data *rdp)
20572057
*/
20582058
rcu_nocb_lock_irqsave(rdp, flags);
20592059
WARN_ON_ONCE(cpu_is_offline(smp_processor_id()));
2060-
pending = rcu_segcblist_n_cbs(&rdp->cblist);
2060+
pending = rcu_segcblist_get_seglen(&rdp->cblist, RCU_DONE_TAIL);
20612061
div = READ_ONCE(rcu_divisor);
20622062
div = div < 0 ? 7 : div > sizeof(long) * 8 - 2 ? sizeof(long) * 8 - 2 : div;
20632063
bl = max(rdp->blimit, pending >> div);

0 commit comments

Comments
 (0)