@@ -382,6 +382,155 @@ static const struct ref_scale_ops percpuinc_ops = {
382382 .name = "percpuinc"
383383};
384384
385+ // Note that this can lose counts in preemptible kernels.
386+ static void ref_incpercpu_section (const int nloops )
387+ {
388+ int i ;
389+
390+ for (i = nloops ; i >= 0 ; i -- ) {
391+ unsigned long * tap = this_cpu_ptr (& test_acqrel );
392+
393+ WRITE_ONCE (* tap , READ_ONCE (* tap ) + 1 );
394+ WRITE_ONCE (* tap , READ_ONCE (* tap ) - 1 );
395+ }
396+ }
397+
398+ static void ref_incpercpu_delay_section (const int nloops , const int udl , const int ndl )
399+ {
400+ int i ;
401+
402+ for (i = nloops ; i >= 0 ; i -- ) {
403+ unsigned long * tap = this_cpu_ptr (& test_acqrel );
404+
405+ WRITE_ONCE (* tap , READ_ONCE (* tap ) + 1 );
406+ un_delay (udl , ndl );
407+ WRITE_ONCE (* tap , READ_ONCE (* tap ) - 1 );
408+ }
409+ }
410+
411+ static const struct ref_scale_ops incpercpu_ops = {
412+ .init = rcu_sync_scale_init ,
413+ .readsection = ref_incpercpu_section ,
414+ .delaysection = ref_incpercpu_delay_section ,
415+ .name = "incpercpu"
416+ };
417+
418+ static void ref_incpercpupreempt_section (const int nloops )
419+ {
420+ int i ;
421+
422+ for (i = nloops ; i >= 0 ; i -- ) {
423+ unsigned long * tap ;
424+
425+ preempt_disable ();
426+ tap = this_cpu_ptr (& test_acqrel );
427+ WRITE_ONCE (* tap , READ_ONCE (* tap ) + 1 );
428+ WRITE_ONCE (* tap , READ_ONCE (* tap ) - 1 );
429+ preempt_enable ();
430+ }
431+ }
432+
433+ static void ref_incpercpupreempt_delay_section (const int nloops , const int udl , const int ndl )
434+ {
435+ int i ;
436+
437+ for (i = nloops ; i >= 0 ; i -- ) {
438+ unsigned long * tap ;
439+
440+ preempt_disable ();
441+ tap = this_cpu_ptr (& test_acqrel );
442+ WRITE_ONCE (* tap , READ_ONCE (* tap ) + 1 );
443+ un_delay (udl , ndl );
444+ WRITE_ONCE (* tap , READ_ONCE (* tap ) - 1 );
445+ preempt_enable ();
446+ }
447+ }
448+
449+ static const struct ref_scale_ops incpercpupreempt_ops = {
450+ .init = rcu_sync_scale_init ,
451+ .readsection = ref_incpercpupreempt_section ,
452+ .delaysection = ref_incpercpupreempt_delay_section ,
453+ .name = "incpercpupreempt"
454+ };
455+
456+ static void ref_incpercpubh_section (const int nloops )
457+ {
458+ int i ;
459+
460+ for (i = nloops ; i >= 0 ; i -- ) {
461+ unsigned long * tap ;
462+
463+ local_bh_disable ();
464+ tap = this_cpu_ptr (& test_acqrel );
465+ WRITE_ONCE (* tap , READ_ONCE (* tap ) + 1 );
466+ WRITE_ONCE (* tap , READ_ONCE (* tap ) - 1 );
467+ local_bh_enable ();
468+ }
469+ }
470+
471+ static void ref_incpercpubh_delay_section (const int nloops , const int udl , const int ndl )
472+ {
473+ int i ;
474+
475+ for (i = nloops ; i >= 0 ; i -- ) {
476+ unsigned long * tap ;
477+
478+ local_bh_disable ();
479+ tap = this_cpu_ptr (& test_acqrel );
480+ WRITE_ONCE (* tap , READ_ONCE (* tap ) + 1 );
481+ un_delay (udl , ndl );
482+ WRITE_ONCE (* tap , READ_ONCE (* tap ) - 1 );
483+ local_bh_enable ();
484+ }
485+ }
486+
487+ static const struct ref_scale_ops incpercpubh_ops = {
488+ .init = rcu_sync_scale_init ,
489+ .readsection = ref_incpercpubh_section ,
490+ .delaysection = ref_incpercpubh_delay_section ,
491+ .name = "incpercpubh"
492+ };
493+
494+ static void ref_incpercpuirqsave_section (const int nloops )
495+ {
496+ int i ;
497+ unsigned long flags ;
498+
499+ for (i = nloops ; i >= 0 ; i -- ) {
500+ unsigned long * tap ;
501+
502+ local_irq_save (flags );
503+ tap = this_cpu_ptr (& test_acqrel );
504+ WRITE_ONCE (* tap , READ_ONCE (* tap ) + 1 );
505+ WRITE_ONCE (* tap , READ_ONCE (* tap ) - 1 );
506+ local_irq_restore (flags );
507+ }
508+ }
509+
510+ static void ref_incpercpuirqsave_delay_section (const int nloops , const int udl , const int ndl )
511+ {
512+ int i ;
513+ unsigned long flags ;
514+
515+ for (i = nloops ; i >= 0 ; i -- ) {
516+ unsigned long * tap ;
517+
518+ local_irq_save (flags );
519+ tap = this_cpu_ptr (& test_acqrel );
520+ WRITE_ONCE (* tap , READ_ONCE (* tap ) + 1 );
521+ un_delay (udl , ndl );
522+ WRITE_ONCE (* tap , READ_ONCE (* tap ) - 1 );
523+ local_irq_restore (flags );
524+ }
525+ }
526+
527+ static const struct ref_scale_ops incpercpuirqsave_ops = {
528+ .init = rcu_sync_scale_init ,
529+ .readsection = ref_incpercpuirqsave_section ,
530+ .delaysection = ref_incpercpuirqsave_delay_section ,
531+ .name = "incpercpuirqsave"
532+ };
533+
385534// Definitions for rwlock
386535static rwlock_t test_rwlock ;
387536
@@ -1318,8 +1467,10 @@ ref_scale_init(void)
13181467 int firsterr = 0 ;
13191468 static const struct ref_scale_ops * scale_ops [] = {
13201469 & rcu_ops , & srcu_ops , & srcu_fast_ops , RCU_TRACE_OPS RCU_TASKS_OPS
1321- & refcnt_ops , & rwlock_ops , & rwsem_ops , & lock_ops , & lock_irq_ops ,
1322- & percpuinc_ops , & acqrel_ops , & sched_clock_ops , & clock_ops , & jiffies_ops ,
1470+ & refcnt_ops , & percpuinc_ops , & incpercpu_ops , & incpercpupreempt_ops ,
1471+ & incpercpubh_ops , & incpercpuirqsave_ops ,
1472+ & rwlock_ops , & rwsem_ops , & lock_ops , & lock_irq_ops , & acqrel_ops ,
1473+ & sched_clock_ops , & clock_ops , & jiffies_ops ,
13231474 & preempt_ops , & bh_ops , & irq_ops , & irqsave_ops ,
13241475 & typesafe_ref_ops , & typesafe_lock_ops , & typesafe_seqlock_ops ,
13251476 };
0 commit comments