@@ -175,6 +175,15 @@ module_param(gp_init_delay, int, 0444);
175
175
static int gp_cleanup_delay ;
176
176
module_param (gp_cleanup_delay , int , 0444 );
177
177
178
+ /*
179
+ * This rcu parameter is runtime-read-only. It reflects
180
+ * a minimum allowed number of objects which can be cached
181
+ * per-CPU. Object size is equal to one page. This value
182
+ * can be changed at boot time.
183
+ */
184
+ static int rcu_min_cached_objs = 2 ;
185
+ module_param (rcu_min_cached_objs , int , 0444 );
186
+
178
187
/* Retrieve RCU kthreads priority for rcutorture */
179
188
int rcu_get_gp_kthreads_prio (void )
180
189
{
@@ -2997,7 +3006,6 @@ struct kfree_rcu_cpu_work {
2997
3006
* struct kfree_rcu_cpu - batch up kfree_rcu() requests for RCU grace period
2998
3007
* @head: List of kfree_rcu() objects not yet waiting for a grace period
2999
3008
* @bhead: Bulk-List of kfree_rcu() objects not yet waiting for a grace period
3000
- * @bcached: Keeps at most one object for later reuse when build chain blocks
3001
3009
* @krw_arr: Array of batches of kfree_rcu() objects waiting for a grace period
3002
3010
* @lock: Synchronize access to this structure
3003
3011
* @monitor_work: Promote @head to @head_free after KFREE_DRAIN_JIFFIES
@@ -3013,13 +3021,22 @@ struct kfree_rcu_cpu_work {
3013
3021
struct kfree_rcu_cpu {
3014
3022
struct rcu_head * head ;
3015
3023
struct kfree_rcu_bulk_data * bhead ;
3016
- struct kfree_rcu_bulk_data * bcached ;
3017
3024
struct kfree_rcu_cpu_work krw_arr [KFREE_N_BATCHES ];
3018
3025
raw_spinlock_t lock ;
3019
3026
struct delayed_work monitor_work ;
3020
3027
bool monitor_todo ;
3021
3028
bool initialized ;
3022
3029
int count ;
3030
+
3031
+ /*
3032
+ * A simple cache list that contains objects for
3033
+ * reuse purpose. In order to save some per-cpu
3034
+ * space the list is singular. Even though it is
3035
+ * lockless an access has to be protected by the
3036
+ * per-cpu lock.
3037
+ */
3038
+ struct llist_head bkvcache ;
3039
+ int nr_bkv_objs ;
3023
3040
};
3024
3041
3025
3042
static DEFINE_PER_CPU (struct kfree_rcu_cpu , krc ) = {
@@ -3056,6 +3073,31 @@ krc_this_cpu_unlock(struct kfree_rcu_cpu *krcp, unsigned long flags)
3056
3073
local_irq_restore (flags );
3057
3074
}
3058
3075
3076
+ static inline struct kfree_rcu_bulk_data *
3077
+ get_cached_bnode (struct kfree_rcu_cpu * krcp )
3078
+ {
3079
+ if (!krcp -> nr_bkv_objs )
3080
+ return NULL ;
3081
+
3082
+ krcp -> nr_bkv_objs -- ;
3083
+ return (struct kfree_rcu_bulk_data * )
3084
+ llist_del_first (& krcp -> bkvcache );
3085
+ }
3086
+
3087
+ static inline bool
3088
+ put_cached_bnode (struct kfree_rcu_cpu * krcp ,
3089
+ struct kfree_rcu_bulk_data * bnode )
3090
+ {
3091
+ // Check the limit.
3092
+ if (krcp -> nr_bkv_objs >= rcu_min_cached_objs )
3093
+ return false;
3094
+
3095
+ llist_add ((struct llist_node * ) bnode , & krcp -> bkvcache );
3096
+ krcp -> nr_bkv_objs ++ ;
3097
+ return true;
3098
+
3099
+ }
3100
+
3059
3101
/*
3060
3102
* This function is invoked in workqueue context after a grace period.
3061
3103
* It frees all the objects queued on ->bhead_free or ->head_free.
@@ -3091,7 +3133,12 @@ static void kfree_rcu_work(struct work_struct *work)
3091
3133
kfree_bulk (bhead -> nr_records , bhead -> records );
3092
3134
rcu_lock_release (& rcu_callback_map );
3093
3135
3094
- if (cmpxchg (& krcp -> bcached , NULL , bhead ))
3136
+ krcp = krc_this_cpu_lock (& flags );
3137
+ if (put_cached_bnode (krcp , bhead ))
3138
+ bhead = NULL ;
3139
+ krc_this_cpu_unlock (krcp , flags );
3140
+
3141
+ if (bhead )
3095
3142
free_page ((unsigned long ) bhead );
3096
3143
3097
3144
cond_resched_tasks_rcu_qs ();
@@ -3224,7 +3271,7 @@ kfree_call_rcu_add_ptr_to_bulk(struct kfree_rcu_cpu *krcp,
3224
3271
/* Check if a new block is required. */
3225
3272
if (!krcp -> bhead ||
3226
3273
krcp -> bhead -> nr_records == KFREE_BULK_MAX_ENTR ) {
3227
- bnode = xchg ( & krcp -> bcached , NULL );
3274
+ bnode = get_cached_bnode ( krcp );
3228
3275
if (!bnode ) {
3229
3276
WARN_ON_ONCE (sizeof (struct kfree_rcu_bulk_data ) > PAGE_SIZE );
3230
3277
@@ -4277,12 +4324,23 @@ static void __init kfree_rcu_batch_init(void)
4277
4324
4278
4325
for_each_possible_cpu (cpu ) {
4279
4326
struct kfree_rcu_cpu * krcp = per_cpu_ptr (& krc , cpu );
4327
+ struct kfree_rcu_bulk_data * bnode ;
4280
4328
4281
4329
for (i = 0 ; i < KFREE_N_BATCHES ; i ++ ) {
4282
4330
INIT_RCU_WORK (& krcp -> krw_arr [i ].rcu_work , kfree_rcu_work );
4283
4331
krcp -> krw_arr [i ].krcp = krcp ;
4284
4332
}
4285
4333
4334
+ for (i = 0 ; i < rcu_min_cached_objs ; i ++ ) {
4335
+ bnode = (struct kfree_rcu_bulk_data * )
4336
+ __get_free_page (GFP_NOWAIT | __GFP_NOWARN );
4337
+
4338
+ if (bnode )
4339
+ put_cached_bnode (krcp , bnode );
4340
+ else
4341
+ pr_err ("Failed to preallocate for %d CPU!\n" , cpu );
4342
+ }
4343
+
4286
4344
INIT_DELAYED_WORK (& krcp -> monitor_work , kfree_rcu_monitor );
4287
4345
krcp -> initialized = true;
4288
4346
}
0 commit comments