]> Git Repo - J-linux.git/commitdiff
Merge tag 'printk-for-6.2' of git://git.kernel.org/pub/scm/linux/kernel/git/printk...
authorLinus Torvalds <[email protected]>
Mon, 12 Dec 2022 17:01:36 +0000 (09:01 -0800)
committerLinus Torvalds <[email protected]>
Mon, 12 Dec 2022 17:01:36 +0000 (09:01 -0800)
Pull printk updates from Petr Mladek:

 - Add NMI-safe SRCU reader API. It uses atomic_inc() instead of
   this_cpu_inc() on strong load-store architectures.

 - Introduce new console_list_lock to synchronize a manipulation of the
   list of registered consoles and their flags.

   This is a first step in removing the big-kernel-lock-like behavior of
   console_lock(). This semaphore still serializes console->write()
   calbacks against:

      - each other. It primary prevents potential races between early
        and proper console drivers using the same device.

      - suspend()/resume() callbacks and init() operations in some
        drivers.

      - various other operations in the tty/vt and framebufer
        susbsystems. It is likely that console_lock() serializes even
        operations that are not directly conflicting with the
        console->write() callbacks here. This is the most complicated
        big-kernel-lock aspect of the console_lock() that will be hard
        to untangle.

 - Introduce new console_srcu lock that is used to safely iterate and
   access the registered console drivers under SRCU read lock.

   This is a prerequisite for introducing atomic console drivers and
   console kthreads. It will reduce the complexity of serialization
   against normal consoles and console_lock(). Also it should remove the
   risk of deadlock during critical situations, like Oops or panic, when
   only atomic consoles are registered.

 - Check whether the console is registered instead of enabled on many
   locations. It was a historical leftover.

 - Cleanly force a preferred console in xenfb code instead of a dirty
   hack.

 - A lot of code and comment clean ups and improvements.

* tag 'printk-for-6.2' of git://git.kernel.org/pub/scm/linux/kernel/git/printk/linux: (47 commits)
  printk: htmldocs: add missing description
  tty: serial: sh-sci: use setup() callback for early console
  printk: relieve console_lock of list synchronization duties
  tty: serial: kgdboc: use console_list_lock to trap exit
  tty: serial: kgdboc: synchronize tty_find_polling_driver() and register_console()
  tty: serial: kgdboc: use console_list_lock for list traversal
  tty: serial: kgdboc: use srcu console list iterator
  proc: consoles: use console_list_lock for list iteration
  tty: tty_io: use console_list_lock for list synchronization
  printk, xen: fbfront: create/use safe function for forcing preferred
  netconsole: avoid CON_ENABLED misuse to track registration
  usb: early: xhci-dbc: use console_is_registered()
  tty: serial: xilinx_uartps: use console_is_registered()
  tty: serial: samsung_tty: use console_is_registered()
  tty: serial: pic32_uart: use console_is_registered()
  tty: serial: earlycon: use console_is_registered()
  tty: hvc: use console_is_registered()
  efi: earlycon: use console_is_registered()
  tty: nfcon: use console_is_registered()
  serial_core: replace uart_console_enabled() with uart_console_registered()
  ...

1  2 
.clang-format
include/linux/rcutiny.h
kernel/rcu/Kconfig
kernel/rcu/rcu.h
lib/test_printf.c

diff --combined .clang-format
index 8d01225bfcb7d7bc65d0093a89a7e76d710f3588,04a675b56b579fa1cc35902ade8afbd76c4de940..bcf60344f9f5b07b072d50c9bbd52f173f38ef69
@@@ -222,6 -222,7 +222,7 @@@ ForEachMacros
    - 'for_each_component_dais'
    - 'for_each_component_dais_safe'
    - 'for_each_console'
+   - 'for_each_console_srcu'
    - 'for_each_cpu'
    - 'for_each_cpu_and'
    - 'for_each_cpu_not'
    - 'perf_hpp_list__for_each_sort_list_safe'
    - 'perf_pmu__for_each_hybrid_pmu'
    - 'ping_portaddr_for_each_entry'
 +  - 'ping_portaddr_for_each_entry_rcu'
    - 'plist_for_each'
    - 'plist_for_each_continue'
    - 'plist_for_each_entry'
diff --combined include/linux/rcutiny.h
index 5c271bf3a1e7e3719c6bac630552081ddfb97a80,d40b21ec7e0da0f19e0b38f7891e0af4a23409a2..68f9070aa1110a659c6c17bc037a92c89fa21632
@@@ -142,21 -142,19 +142,17 @@@ static inline int rcu_needs_cpu(void
   * Take advantage of the fact that there is only one CPU, which
   * allows us to ignore virtualization-based context switches.
   */
 -static inline void rcu_virt_note_context_switch(int cpu) { }
 +static inline void rcu_virt_note_context_switch(void) { }
  static inline void rcu_cpu_stall_reset(void) { }
  static inline int rcu_jiffies_till_stall_check(void) { return 21 * HZ; }
  static inline void rcu_irq_exit_check_preempt(void) { }
 -#define rcu_is_idle_cpu(cpu) \
 -      (is_idle_task(current) && !in_nmi() && !in_hardirq() && !in_serving_softirq())
  static inline void exit_rcu(void) { }
  static inline bool rcu_preempt_need_deferred_qs(struct task_struct *t)
  {
        return false;
  }
  static inline void rcu_preempt_deferred_qs(struct task_struct *t) { }
- #ifdef CONFIG_SRCU
  void rcu_scheduler_starting(void);
- #else /* #ifndef CONFIG_SRCU */
- static inline void rcu_scheduler_starting(void) { }
- #endif /* #else #ifndef CONFIG_SRCU */
  static inline void rcu_end_inkernel_boot(void) { }
  static inline bool rcu_inkernel_boot_has_ended(void) { return true; }
  static inline bool rcu_is_watching(void) { return true; }
diff --combined kernel/rcu/Kconfig
index 05106e6fbd0edd5b9432db53151b9765cdb35872,1b0d79b2f5fa0859f9289b84fcd3e96c9507bf80..ab62074174c32d184d51d13cd158bdb30d3da6cb
@@@ -54,21 -54,17 +54,17 @@@ config RCU_EXPER
          Say N if you are unsure.
  
  config SRCU
-       bool
-       help
-         This option selects the sleepable version of RCU. This version
-         permits arbitrary sleeping or blocking within RCU read-side critical
-         sections.
+       def_bool y
  
  config TINY_SRCU
        bool
-       default y if SRCU && TINY_RCU
+       default y if TINY_RCU
        help
          This option selects the single-CPU non-preemptible version of SRCU.
  
  config TREE_SRCU
        bool
-       default y if SRCU && !TINY_RCU
+       default y if !TINY_RCU
        help
          This option selects the full-fledged version of SRCU.
  
@@@ -77,7 -73,6 +73,6 @@@ config NEED_SRCU_NMI_SAF
  
  config TASKS_RCU_GENERIC
        def_bool TASKS_RCU || TASKS_RUDE_RCU || TASKS_TRACE_RCU
-       select SRCU
        help
          This option enables generic infrastructure code supporting
          task-based RCU implementations.  Not for manual selection.
@@@ -314,12 -309,4 +309,12 @@@ config TASKS_TRACE_RCU_READ_M
          Say N here if you hate read-side memory barriers.
          Take the default if you are unsure.
  
 +config RCU_LAZY
 +      bool "RCU callback lazy invocation functionality"
 +      depends on RCU_NOCB_CPU
 +      default n
 +      help
 +        To save power, batch RCU callbacks and flush after delay, memory
 +        pressure, or callback list growing too big.
 +
  endmenu # "RCU Subsystem"
diff --combined kernel/rcu/rcu.h
index 65704cbc9df7b3d6630e7a6dd4eb58f08341ce3b,1f7ca484483a1c7a7b7e272ec6b920d936ec5e96..c5aa934de59b04e9f9965826c07bbbead783bd5f
@@@ -286,7 -286,7 +286,7 @@@ void rcu_test_sync_prims(void)
   */
  extern void resched_cpu(int cpu);
  
- #if defined(CONFIG_SRCU) || !defined(CONFIG_TINY_RCU)
+ #if !defined(CONFIG_TINY_RCU)
  
  #include <linux/rcu_node_tree.h>
  
@@@ -375,6 -375,10 +375,10 @@@ extern void rcu_init_geometry(void)
             (cpu) <= rnp->grphi; \
             (cpu) = rcu_find_next_bit((rnp), (cpu) + 1 - (rnp->grplo), (mask)))
  
+ #endif /* !defined(CONFIG_TINY_RCU) */
+ #if !defined(CONFIG_TINY_RCU) || defined(CONFIG_TASKS_RCU_GENERIC)
  /*
   * Wrappers for the rcu_node::lock acquire and release.
   *
@@@ -437,7 -441,7 +441,7 @@@ do {                                                                       
  #define raw_lockdep_assert_held_rcu_node(p)                           \
        lockdep_assert_held(&ACCESS_PRIVATE(p, lock))
  
- #endif /* #if defined(CONFIG_SRCU) || !defined(CONFIG_TINY_RCU) */
+ #endif // #if !defined(CONFIG_TINY_RCU) || defined(CONFIG_TASKS_RCU_GENERIC)
  
  #ifdef CONFIG_TINY_RCU
  /* Tiny RCU doesn't expedite, as its purpose in life is instead to be tiny. */
@@@ -474,14 -478,6 +478,14 @@@ enum rcutorture_type 
        INVALID_RCU_FLAVOR
  };
  
 +#if defined(CONFIG_RCU_LAZY)
 +unsigned long rcu_lazy_get_jiffies_till_flush(void);
 +void rcu_lazy_set_jiffies_till_flush(unsigned long j);
 +#else
 +static inline unsigned long rcu_lazy_get_jiffies_till_flush(void) { return 0; }
 +static inline void rcu_lazy_set_jiffies_till_flush(unsigned long j) { }
 +#endif
 +
  #if defined(CONFIG_TREE_RCU)
  void rcutorture_get_gp_data(enum rcutorture_type test_type, int *flags,
                            unsigned long *gp_seq);
diff --combined lib/test_printf.c
index 5eb889679e4faf1e3e477fa59a3805b3e710a368,1fb12c1a0fa95e24dc57c75e1b4843ae3230078d..d6a5d4b5f88452db9743a6a5645edc98ded0b14b
@@@ -179,6 -179,18 +179,6 @@@ test_number(void
         * behaviour.
         */
        test("00|0|0|0|0", "%.2d|%.1d|%.0d|%.*d|%1.0d", 0, 0, 0, 0, 0, 0);
 -#ifndef __CHAR_UNSIGNED__
 -      {
 -              /*
 -               * Passing a 'char' to a %02x specifier doesn't do
 -               * what was presumably the intention when char is
 -               * signed and the value is negative. One must either &
 -               * with 0xff or cast to u8.
 -               */
 -              char val = -16;
 -              test("0xfffffff0|0xf0|0xf0", "%#02x|%#02x|%#02x", val, val & 0xff, (u8)val);
 -      }
 -#endif
  }
  
  static void __init
@@@ -692,31 -704,29 +692,29 @@@ flags(void
  
  static void __init fwnode_pointer(void)
  {
-       const struct software_node softnodes[] = {
-               { .name = "first", },
-               { .name = "second", .parent = &softnodes[0], },
-               { .name = "third", .parent = &softnodes[1], },
-               { NULL /* Guardian */ }
-       };
-       const char * const full_name = "first/second/third";
+       const struct software_node first = { .name = "first" };
+       const struct software_node second = { .name = "second", .parent = &first };
+       const struct software_node third = { .name = "third", .parent = &second };
+       const struct software_node *group[] = { &first, &second, &third, NULL };
        const char * const full_name_second = "first/second";
+       const char * const full_name_third = "first/second/third";
        const char * const second_name = "second";
        const char * const third_name = "third";
        int rval;
  
-       rval = software_node_register_nodes(softnodes);
+       rval = software_node_register_node_group(group);
        if (rval) {
                pr_warn("cannot register softnodes; rval %d\n", rval);
                return;
        }
  
-       test(full_name_second, "%pfw", software_node_fwnode(&softnodes[1]));
-       test(full_name, "%pfw", software_node_fwnode(&softnodes[2]));
-       test(full_name, "%pfwf", software_node_fwnode(&softnodes[2]));
-       test(second_name, "%pfwP", software_node_fwnode(&softnodes[1]));
-       test(third_name, "%pfwP", software_node_fwnode(&softnodes[2]));
+       test(full_name_second, "%pfw", software_node_fwnode(&second));
+       test(full_name_third, "%pfw", software_node_fwnode(&third));
+       test(full_name_third, "%pfwf", software_node_fwnode(&third));
+       test(second_name, "%pfwP", software_node_fwnode(&second));
+       test(third_name, "%pfwP", software_node_fwnode(&third));
  
-       software_node_unregister_nodes(softnodes);
+       software_node_unregister_node_group(group);
  }
  
  static void __init fourcc_pointer(void)
This page took 0.086541 seconds and 4 git commands to generate.