@@ -210,14 +210,17 @@ static bool test_state(unsigned int *tasks, enum psi_states state)
210
210
}
211
211
}
212
212
213
- static void get_recent_times (struct psi_group * group , int cpu , u32 * times )
213
+ static void get_recent_times (struct psi_group * group , int cpu , u32 * times ,
214
+ u32 * pchanged_states )
214
215
{
215
216
struct psi_group_cpu * groupc = per_cpu_ptr (group -> pcpu , cpu );
216
217
u64 now , state_start ;
217
218
enum psi_states s ;
218
219
unsigned int seq ;
219
220
u32 state_mask ;
220
221
222
+ * pchanged_states = 0 ;
223
+
221
224
/* Snapshot a coherent view of the CPU state */
222
225
do {
223
226
seq = read_seqcount_begin (& groupc -> seq );
@@ -246,6 +249,8 @@ static void get_recent_times(struct psi_group *group, int cpu, u32 *times)
246
249
groupc -> times_prev [s ] = times [s ];
247
250
248
251
times [s ] = delta ;
252
+ if (delta )
253
+ * pchanged_states |= (1 << s );
249
254
}
250
255
}
251
256
@@ -269,10 +274,11 @@ static void calc_avgs(unsigned long avg[3], int missed_periods,
269
274
avg [2 ] = calc_load (avg [2 ], EXP_300s , pct );
270
275
}
271
276
272
- static bool collect_percpu_times (struct psi_group * group )
277
+ static void collect_percpu_times (struct psi_group * group , u32 * pchanged_states )
273
278
{
274
279
u64 deltas [NR_PSI_STATES - 1 ] = { 0 , };
275
280
unsigned long nonidle_total = 0 ;
281
+ u32 changed_states = 0 ;
276
282
int cpu ;
277
283
int s ;
278
284
@@ -287,8 +293,11 @@ static bool collect_percpu_times(struct psi_group *group)
287
293
for_each_possible_cpu (cpu ) {
288
294
u32 times [NR_PSI_STATES ];
289
295
u32 nonidle ;
296
+ u32 cpu_changed_states ;
290
297
291
- get_recent_times (group , cpu , times );
298
+ get_recent_times (group , cpu , times ,
299
+ & cpu_changed_states );
300
+ changed_states |= cpu_changed_states ;
292
301
293
302
nonidle = nsecs_to_jiffies (times [PSI_NONIDLE ]);
294
303
nonidle_total += nonidle ;
@@ -313,7 +322,8 @@ static bool collect_percpu_times(struct psi_group *group)
313
322
for (s = 0 ; s < NR_PSI_STATES - 1 ; s ++ )
314
323
group -> total [s ] += div_u64 (deltas [s ], max (nonidle_total , 1UL ));
315
324
316
- return nonidle_total ;
325
+ if (pchanged_states )
326
+ * pchanged_states = changed_states ;
317
327
}
318
328
319
329
static u64 update_averages (struct psi_group * group , u64 now )
@@ -373,6 +383,7 @@ static void psi_avgs_work(struct work_struct *work)
373
383
{
374
384
struct delayed_work * dwork ;
375
385
struct psi_group * group ;
386
+ u32 changed_states ;
376
387
bool nonidle ;
377
388
u64 now ;
378
389
@@ -383,7 +394,8 @@ static void psi_avgs_work(struct work_struct *work)
383
394
384
395
now = sched_clock ();
385
396
386
- nonidle = collect_percpu_times (group );
397
+ collect_percpu_times (group , & changed_states );
398
+ nonidle = changed_states & (1 << PSI_NONIDLE );
387
399
/*
388
400
* If there is task activity, periodically fold the per-cpu
389
401
* times and feed samples into the running averages. If things
@@ -719,7 +731,7 @@ int psi_show(struct seq_file *m, struct psi_group *group, enum psi_res res)
719
731
/* Update averages before reporting them */
720
732
mutex_lock (& group -> avgs_lock );
721
733
now = sched_clock ();
722
- collect_percpu_times (group );
734
+ collect_percpu_times (group , NULL );
723
735
if (now >= group -> avg_next_update )
724
736
group -> avg_next_update = update_averages (group , now );
725
737
mutex_unlock (& group -> avgs_lock );
0 commit comments