v5.17-rc5-rt9
Subsystems (17)
Dear RT folks!
I'm pleased to announce the v5.17-rc5-rt9 patch set.
Changes since v5.17-rc5-rt8:
- Update the memcg patches to v5.
- Update the networking patches to v3 and include the follow-up patches.
- Update the patches for the random subsystem to the latest version as committed to the the subsystem's git tree.
- Update the delayed task-struct free patches to v2.
- Update the generic_handle_irq_safe() patches to v4.
Known issues
- Valentin Schneider reported a few splats on ARM64, see
https://lkml.kernel.org/r/[email protected]
The delta patch against v5.17-rc5-rt8 is appended below and can be found here:
https://cdn.kernel.org/pub/linux/kernel/projects/rt/5.17/incr/patch-5.17-rc5-rt8-rt9.patch.xz
You can get this release via the git tree at:
git://git.kernel.org/pub/scm/linux/kernel/git/rt/linux-rt-devel.git v5.17-rc5-rt9
The RT patch against v5.17-rc5 can be found here:
https://cdn.kernel.org/pub/linux/kernel/projects/rt/5.17/older/patch-5.17-rc5-rt9.patch.xz
The split quilt queue is available at:
https://cdn.kernel.org/pub/linux/kernel/projects/rt/5.17/older/patches-5.17-rc5-rt9.tar.xz
Sebastian
drivers/char/random.c +69 -38
@@ -401,13 +401,12 @@ static void mix_pool_bytes(const void *in, int nbytes) }struct fast_pool { +u32 pool[4 ];struct work_struct mix;unsigned long last; -u32 pool[4 ];unsigned int count;u16 reg_idx; }; -#define FAST_POOL_MIX_INFLIGHT (1U << 31)/* * This is a fast mixing routine used by the interrupt randomness
@@ -719,12 +718,13 @@ static size_t crng_fast_load(const u8 *cp, size_t len) p[crng_init_cnt %CHACHA_KEY_SIZE ] ^= *cp; cp++; crng_init_cnt++; len--; ret++; } -spin_unlock_irqrestore (&primary_crng.lock, flags);if (crng_init_cnt >=CRNG_INIT_CNT_THRESH ) {invalidate_batched_entropy (); crng_init =1 ; -pr_notice ("fast init done\n" ); } +spin_unlock_irqrestore (&primary_crng.lock, flags); +if (crng_init ==1 ) +pr_notice ("fast init done\n" );return ret; }
@@ -1006,6 +1006,29 @@ EXPORT_SYMBOL_GPL(add_input_randomness); static DEFINE_PER_CPU(struct fast_pool, irq_randomness); +#ifdef CONFIG_SMP +/* +* This function is called when the CPU has just come online, with +* entry CPUHP_AP_RANDOM_ONLINE, just after CPUHP_AP_WORKQUEUE_ONLINE. +*/ +int random_online_cpu (unsigned int cpu) +{ +/* +* During CPU shutdown and before CPU onlining, add_interrupt_ +* randomness() may schedule mix_interrupt_randomness(), and +* set the MIX_INFLIGHT flag. However, because the worker can +* be scheduled on a different CPU during this period, that +* flag will never be cleared. For that reason, we zero out +* the flag here, which runs just after workqueues are onlined +* for the CPU again. This also has the effect of setting the +* irq randomness count to zero so that new accumulated irqs +* are fresh. +*/ +per_cpu_ptr (&irq_randomness, cpu)->count =0 ; +return 0 ; +} +#endif +#ifdef ADD_INTERRUPT_BENCH static unsigned long avg_cycles, avg_deviation;
@@ -1045,29 +1068,23 @@ static u32 get_reg(struct fast_pool *f, struct pt_regs *regs)static void mix_interrupt_randomness (struct work_struct *work) { struct fast_pool *fast_pool = container_of(work, struct fast_pool, mix); -u8 pool[sizeof (fast_pool->pool)]; +u32 pool[4 ]; -if (unlikely (crng_init ==0 )) { -size_t ret; - - ret =crng_fast_load ((u8 *)fast_pool->pool,sizeof (fast_pool->pool)); -if (ret) { -WRITE_ONCE (fast_pool->count,0 ); - fast_pool->last = jiffies; -return ; - } +/* Check to see if we're running on the wrong CPU due to hotplug. */ +local_irq_disable (); +if (fast_pool !=this_cpu_ptr (&irq_randomness)) { +local_irq_enable (); +return ; }/* -* Since this is the result of a trip through the scheduler, xor in -* a cycle counter. It can't hurt, and might help. +* Copy the pool to the stack so that the mixer always has a +* consistent view, before we reenable irqs again. */ - fast_pool->pool[3 ] ^=random_get_entropy (); -/* Copy the pool to the stack so that the mixer always has a consistent view. */ memcpy (pool, fast_pool->pool,sizeof (pool)); -/* We take care to zero out the count only after we're done reading the pool. */ -WRITE_ONCE (fast_pool->count,0 ); + fast_pool->count =0 ; fast_pool->last = jiffies; +local_irq_enable ();mix_pool_bytes (pool,sizeof (pool));credit_entropy_bits (1 );
@@ -1076,13 +1093,14 @@ static void mix_interrupt_randomness(struct work_struct *work)void add_interrupt_randomness (int irq) { +enum {MIX_INFLIGHT =1U <<31 };struct fast_pool *fast_pool =this_cpu_ptr (&irq_randomness);struct pt_regs *regs =get_irq_regs ();unsigned long now = jiffies;cycles_t cycles =random_get_entropy (); -unsigned int new_count;u32 c_high, j_high;u64 ip; +unsigned int new_count;if (cycles ==0 ) cycles =get_reg (fast_pool, regs);
@@ -1096,33 +1114,28 @@ void add_interrupt_randomness(int irq) (sizeof (ip) >4 ) ? ip >>32 :get_reg (fast_pool, regs);fast_mix (fast_pool); -add_interrupt_bench (cycles); new_count = ++fast_pool->count; +add_interrupt_bench (cycles); +if (unlikely (crng_init ==0 )) { -if (new_count &FAST_POOL_MIX_INFLIGHT ) -return ; - -if (new_count <64 ) -return ; - - fast_pool->count |=FAST_POOL_MIX_INFLIGHT ; -if (unlikely (!fast_pool->mix.func)) -INIT_WORK (&fast_pool->mix, mix_interrupt_randomness); -queue_work_on (raw_smp_processor_id (), system_highpri_wq, - &fast_pool->mix); +if ((new_count >=64 ) && +crng_fast_load ((u8 *)fast_pool->pool,sizeof (fast_pool->pool)) >0 ) { + fast_pool->count =0 ; + fast_pool->last = now; + }return ; } -if (new_count &FAST_POOL_MIX_INFLIGHT ) +if (new_count &MIX_INFLIGHT )return ; -if (new_count <64 && !time_after (now, fast_pool->last +HZ )) +if ((new_count <64 ) && !time_after (now, fast_pool->last +HZ ))return ;if (unlikely (!fast_pool->mix.func))INIT_WORK (&fast_pool->mix, mix_interrupt_randomness); - fast_pool->count |=FAST_POOL_MIX_INFLIGHT ; + fast_pool->count |=MIX_INFLIGHT ;queue_work_on (raw_smp_processor_id (), system_highpri_wq, &fast_pool->mix); }EXPORT_SYMBOL_GPL (add_interrupt_randomness);
@@ -1945,7 +1958,7 @@ u64 get_random_u64(void) batch =raw_cpu_ptr (&batched_entropy_u64); next_gen =atomic_read (&batch_generation); -if (batch->position %ARRAY_SIZE (batch->entropy_u64) ==0 || +if (batch->position >=ARRAY_SIZE (batch->entropy_u64) || next_gen != batch->generation) {extract_crng ((u8 *)batch->entropy_u64); batch->position =0 ;
@@ -1976,7 +1989,7 @@ u32 get_random_u32(void) batch =raw_cpu_ptr (&batched_entropy_u32); next_gen =atomic_read (&batch_generation); -if (batch->position %ARRAY_SIZE (batch->entropy_u32) ==0 || +if (batch->position >=ARRAY_SIZE (batch->entropy_u32) || next_gen != batch->generation) {extract_crng ((u8 *)batch->entropy_u32); batch->position =0 ;
@@ -1989,6 +2002,24 @@ u32 get_random_u32(void) }EXPORT_SYMBOL (get_random_u32); +#ifdef CONFIG_SMP +/* +* This function is called when the CPU is coming up, with entry +* CPUHP_RANDOM_PREPARE, which comes before CPUHP_WORKQUEUE_PREP. +*/ +int random_prepare_cpu (unsigned int cpu) +{ +/* +* When the cpu comes back online, immediately invalidate both +* the per-cpu crng and all batches, so that we serve fresh +* randomness. +*/ +per_cpu_ptr (&batched_entropy_u32, cpu)->position =UINT_MAX ; +per_cpu_ptr (&batched_entropy_u64, cpu)->position =UINT_MAX ; +return 0 ; +} +#endif +/* It's important to invalidate all potential batched entropy that might * be stored before the crng is initialized, which we can do lazily by * bumping the generation counter.
drivers/net/amt.c +2 -2
@@ -2373,7 +2373,7 @@ static bool amt_membership_query_handler(struct amt_dev *amt, skb->pkt_type =PACKET_MULTICAST ; skb->ip_summed =CHECKSUM_NONE ; len = skb->len; -if (netif_rx (skb) ==NET_RX_SUCCESS ) { +if (__netif_rx (skb) ==NET_RX_SUCCESS ) {amt_update_gw_status (amt,AMT_STATUS_RECEIVED_QUERY , true);dev_sw_netstats_rx_add (amt->dev, len); }else {
@@ -2470,7 +2470,7 @@ static bool amt_update_handler(struct amt_dev *amt, struct sk_buff *skb) skb->pkt_type =PACKET_MULTICAST ; skb->ip_summed =CHECKSUM_NONE ; len = skb->len; -if (netif_rx (skb) ==NET_RX_SUCCESS ) { +if (__netif_rx (skb) ==NET_RX_SUCCESS ) {amt_update_relay_status (tunnel,AMT_STATUS_RECEIVED_UPDATE , true);dev_sw_netstats_rx_add (amt->dev, len);
drivers/net/geneve.c +2 -2
@@ -925,7 +925,7 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev, } skb->protocol =eth_type_trans (skb, geneve->dev); -netif_rx (skb); +__netif_rx (skb);dst_release (&rt->dst);return -EMSGSIZE ; }
@@ -1021,7 +1021,7 @@ static int geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev, } skb->protocol =eth_type_trans (skb, geneve->dev); -netif_rx (skb); +__netif_rx (skb);dst_release (dst);return -EMSGSIZE ; }
drivers/net/gtp.c +1 -1
@@ -207,7 +207,7 @@ static int gtp_rx(struct pdp_ctx *pctx, struct sk_buff *skb,dev_sw_netstats_rx_add (pctx->dev, skb->len); -netif_rx (skb); +__netif_rx (skb);return 0 ; err:
drivers/net/loopback.c +1 -1
@@ -78,7 +78,7 @@ static netdev_tx_t loopback_xmit(struct sk_buff *skb,skb_orphan (skb); -/* Before queueing this packet to netif_rx(), +/* Before queueing this packet to __netif_rx(), * make sure dst is refcounted. */ skb_dst_force (skb);
drivers/net/macsec.c +3 -3
@@ -1033,7 +1033,7 @@ static enum rx_handler_result handle_not_macsec(struct sk_buff *skb)else nskb->pkt_type =PACKET_MULTICAST ; -netif_rx (nskb); +__netif_rx (nskb); }continue ; }
@@ -1056,7 +1056,7 @@ static enum rx_handler_result handle_not_macsec(struct sk_buff *skb) nskb->dev = ndev; -if (netif_rx (nskb) ==NET_RX_SUCCESS ) { +if (__netif_rx (nskb) ==NET_RX_SUCCESS ) {u64_stats_update_begin (&secy_stats->syncp); secy_stats->stats.InPktsUntagged++;u64_stats_update_end (&secy_stats->syncp);
@@ -1288,7 +1288,7 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb)macsec_reset_skb (nskb, macsec->secy.netdev); - ret =netif_rx (nskb); + ret =__netif_rx (nskb);if (ret ==NET_RX_SUCCESS ) {u64_stats_update_begin (&secy_stats->syncp); secy_stats->stats.InPktsUnknownSCI++;
drivers/net/macvlan.c +2 -2
@@ -410,7 +410,7 @@ static void macvlan_forward_source_one(struct sk_buff *skb,if (ether_addr_equal_64bits (eth_hdr (skb)->h_dest, dev->dev_addr)) nskb->pkt_type =PACKET_HOST ; - ret =netif_rx (nskb); + ret =__netif_rx (nskb);macvlan_count_rx (vlan, len, ret ==NET_RX_SUCCESS , false); }
@@ -468,7 +468,7 @@ static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb)/* forward to original port. */ vlan = src; ret =macvlan_broadcast_one (skb, vlan, eth,0 ) ?: -netif_rx (skb); +__netif_rx (skb); handle_res =RX_HANDLER_CONSUMED ; goto out; }
drivers/net/mhi_net.c +1 -1
@@ -225,7 +225,7 @@ static void mhi_net_dl_callback(struct mhi_device *mhi_dev,u64_stats_inc (&mhi_netdev->stats.rx_packets);u64_stats_add (&mhi_netdev->stats.rx_bytes, skb->len);u64_stats_update_end (&mhi_netdev->stats.rx_syncp); -netif_rx (skb); +__netif_rx (skb); }/* Refill if RX buffers queue becomes low */
drivers/net/ntb_netdev.c +1 -1
@@ -119,7 +119,7 @@ static void ntb_netdev_rx_handler(struct ntb_transport_qp *qp, void *qp_data, skb->protocol =eth_type_trans (skb, ndev); skb->ip_summed =CHECKSUM_NONE ; -if (netif_rx (skb) ==NET_RX_DROP ) { +if (__netif_rx (skb) ==NET_RX_DROP ) { ndev->stats.rx_errors++; ndev->stats.rx_dropped++; }else {
drivers/net/rionet.c +1 -1
@@ -109,7 +109,7 @@ static int rionet_rx_clean(struct net_device *ndev)skb_put (rnet->rx_skb[i],RIO_MAX_MSG_SIZE ); rnet->rx_skb[i]->protocol =eth_type_trans (rnet->rx_skb[i], ndev); - error =netif_rx (rnet->rx_skb[i]); + error =__netif_rx (rnet->rx_skb[i]);if (error ==NET_RX_DROP ) { ndev->stats.rx_dropped++;
drivers/net/sb1000.c +1 -1
@@ -872,7 +872,7 @@ printk("cm0: IP identification: %02x%02x fragment offset: %02x%02x\n", buffer[3/* datagram completed: send to upper level */ skb_trim (skb, dlen); -netif_rx (skb); +__netif_rx (skb); stats->rx_bytes+=dlen; stats->rx_packets++; lp->rx_skb[ns] =NULL ;
drivers/net/veth.c +1 -1
@@ -287,7 +287,7 @@ static int veth_forward_skb(struct net_device *dev, struct sk_buff *skb, {return __dev_forward_skb (dev, skb) ?: xdp ?veth_xdp_rx (rq, skb) : -netif_rx (skb); +__netif_rx (skb); }/* return true if the specified skb has chances of GRO aggregation
drivers/net/vrf.c +1 -1
@@ -418,7 +418,7 @@ static int vrf_local_xmit(struct sk_buff *skb, struct net_device *dev, skb->protocol =eth_type_trans (skb, dev); -if (likely (netif_rx (skb) ==NET_RX_SUCCESS )) +if (likely (__netif_rx (skb) ==NET_RX_SUCCESS ))vrf_rx_stats (dev, len);else this_cpu_inc (dev->dstats->rx_drps);
drivers/net/vxlan.c +1 -1
@@ -2541,7 +2541,7 @@ static void vxlan_encap_bypass(struct sk_buff *skb, struct vxlan_dev *src_vxlan, tx_stats->tx_bytes += len;u64_stats_update_end (&tx_stats->syncp); -if (netif_rx (skb) ==NET_RX_SUCCESS ) { +if (__netif_rx (skb) ==NET_RX_SUCCESS ) {u64_stats_update_begin (&rx_stats->syncp); rx_stats->rx_packets++; rx_stats->rx_bytes += len;
drivers/usb/dwc3/gadget.c +2 -0
@@ -4160,9 +4160,11 @@ static irqreturn_t dwc3_thread_interrupt(int irq, void *_evt)unsigned long flags;irqreturn_t ret =IRQ_NONE ; +local_bh_disable ();spin_lock_irqsave (&dwc->lock, flags); ret =dwc3_process_event_buf (evt);spin_unlock_irqrestore (&dwc->lock, flags); +local_bh_enable ();return ret; }
include/linux/cpuhotplug.h +2 -0
@@ -100,6 +100,7 @@ enum cpuhp_state {CPUHP_AP_ARM_CACHE_B15_RAC_DEAD ,CPUHP_PADATA_DEAD ,CPUHP_AP_DTPM_CPU_DEAD , +CPUHP_RANDOM_PREPARE ,CPUHP_WORKQUEUE_PREP ,CPUHP_POWER_NUMA_PREPARE , CPUHP_HRTIMERS_PREPARE,
@@ -240,6 +241,7 @@ enum cpuhp_state {CPUHP_AP_PERF_CSKY_ONLINE ,CPUHP_AP_WATCHDOG_ONLINE ,CPUHP_AP_WORKQUEUE_ONLINE , +CPUHP_AP_RANDOM_ONLINE ,CPUHP_AP_RCUTREE_ONLINE ,CPUHP_AP_BASE_CACHEINFO_ONLINE , CPUHP_AP_ONLINE_DYN,
include/linux/random.h +5 -0
@@ -158,4 +158,9 @@ static inline bool __init arch_get_random_long_early(unsigned long *v) }#endif +#ifdef CONFIG_SMP +extern int random_prepare_cpu (unsigned int cpu); +extern int random_online_cpu (unsigned int cpu); +#endif +#endif /* _LINUX_RANDOM_H */
include/linux/sched.h +0 -1
@@ -1084,7 +1084,6 @@ struct task_struct {sigset_t saved_sigmask;struct sigpending pending;#ifdef CONFIG_PREEMPT_RT -/* TODO: move me into ->restart_block ? */ struct kernel_siginfo forced_info;#endif unsigned long sas_ss_sp;
include/linux/sched/task_stack.h +0 -8
@@ -70,7 +70,6 @@ static inline void *try_get_task_stack(struct task_struct *tsk) }extern void put_task_stack (struct task_struct *tsk); -extern void put_task_stack_sched (struct task_struct *tsk);#else static inline void *try_get_task_stack (struct task_struct *tsk) {
@@ -78,13 +77,6 @@ static inline void *try_get_task_stack(struct task_struct *tsk) }static inline void put_task_stack (struct task_struct *tsk) {} -static inline void put_task_stack_sched (struct task_struct *tsk) {} -#endif - -#ifdef CONFIG_ARCH_THREAD_STACK_ALLOCATOR -static inline void task_stack_cleanup (struct task_struct *tsk) {} -#else -extern void task_stack_cleanup (struct task_struct *tsk);#endif void exit_task_stack_account (struct task_struct *tsk);
kernel/cpu.c +11 -0
@@ -34,6 +34,7 @@#include <linux/scs.h> #include <linux/percpu-rwsem.h> #include <linux/cpuset.h> +#include <linux/random.h> #include <trace/events/power.h> #define CREATE_TRACE_POINTS
@@ -1659,6 +1660,11 @@ static struct cpuhp_step cpuhp_hp_states[] = { .startup.single = perf_event_init_cpu, .teardown.single = perf_event_exit_cpu, }, + [CPUHP_RANDOM_PREPARE] = { + .name = "random:prepare", + .startup.single = random_prepare_cpu, + .teardown.single = NULL, + }, [CPUHP_WORKQUEUE_PREP] = { .name = "workqueue:prepare", .startup.single = workqueue_prepare_cpu,
@@ -1782,6 +1788,11 @@ static struct cpuhp_step cpuhp_hp_states[] = { .startup.single = workqueue_online_cpu, .teardown.single = workqueue_offline_cpu, }, + [CPUHP_AP_RANDOM_ONLINE] = { + .name = "random:online", + .startup.single = random_online_cpu, + .teardown.single = NULL, + }, [CPUHP_AP_RCUTREE_ONLINE] = { .name = "RCU/tree:online", .startup.single = rcutree_online_cpu,
kernel/exit.c +0 -1
@@ -171,7 +171,6 @@ static void delayed_put_task_struct(struct rcu_head *rhp)kprobe_flush_task (tsk);perf_event_delayed_put (tsk);trace_sched_process_free (tsk); -task_stack_cleanup (tsk);put_task_struct (tsk); }
kernel/fork.c +74 -63
226 lines not on this page · raw message
kernel/irq/irqdesc.c +6 -4
@@ -663,13 +663,15 @@ int generic_handle_irq(unsigned int irq)EXPORT_SYMBOL_GPL (generic_handle_irq);/** -* generic_handle_irq_safe - Invoke the handler for a particular irq +* generic_handle_irq_safe - Invoke the handler for a particular irq from any +* context. * @irq: The irq number to handle * -* Returns: 0 on success, or -EINVAL if conversion has failed +* Returns: 0 on success, a negative value on error. * -* This function must be called either from an IRQ context with irq regs -* initialized or with care from any context. +* This function can be called from any context (IRQ or process context). It +* will report an error if not invoked from IRQ context and the irq has been +* marked to enforce IRQ-context only. */ int generic_handle_irq_safe (unsigned int irq) {
kernel/sched/core.c +2 -5
@@ -4948,11 +4948,8 @@ static struct rq *finish_task_switch(struct task_struct *prev)if (prev->sched_class->task_dead) prev->sched_class->task_dead (prev); -/* -* Cache only the VMAP stack. The final deallocation is in -* delayed_put_task_struct. -*/ -put_task_stack_sched (prev); +/* Task is done with its stack. */ +put_task_stack (prev);put_task_struct_rcu_user (prev); }
localversion-rt +1 -1
@@ -1 +1 @@ --rt8 +-rt9
mm/memcontrol.c +532 -563
1,407 lines not on this page · raw message
net/core/dev.c +27 -8
@@ -4831,26 +4831,40 @@ static int netif_rx_internal(struct sk_buff *skb)return ret; } +/** +* __netif_rx - Slightly optimized version of netif_rx +* @skb: buffer to post +* +* This behaves as netif_rx except that it does not disable bottom halves. +* As a result this function may only be invoked from the interrupt context +* (either hard or soft interrupt). +*/ int __netif_rx (struct sk_buff *skb) {int ret; +lockdep_assert_once (hardirq_count () |softirq_count ()); +trace_netif_rx_entry (skb); ret =netif_rx_internal (skb);trace_netif_rx_exit (ret);return ret; } +EXPORT_SYMBOL (__netif_rx);/** * netif_rx - post buffer to the network code * @skb: buffer to post * * This function receives a packet from a device driver and queues it for -* the upper (protocol) levels to process. It always succeeds. The buffer -* may be dropped during processing for congestion control or by the -* protocol layers. -* This interface is considered legacy. Modern NIC driver should use NAPI -* and GRO. +* the upper (protocol) levels to process via the backlog NAPI device. It +* always succeeds. The buffer may be dropped during processing for +* congestion control or by the protocol layers. +* The network buffer is passed via the backlog NAPI device. Modern NIC +* driver should use NAPI and GRO. +* This function can used from interrupt and from process context. The +* caller from process context must not disable interrupts before invoking +* this function. * * return values: * NET_RX_SUCCESS (no congestion)
@@ -4859,11 +4873,16 @@ int __netif_rx(struct sk_buff *skb)*/ int netif_rx (struct sk_buff *skb) { +bool need_bh_off = !(hardirq_count () |softirq_count ());int ret; -local_bh_disable (); - ret =__netif_rx (skb); -local_bh_enable (); +if (need_bh_off) +local_bh_disable (); +trace_netif_rx_entry (skb); + ret =netif_rx_internal (skb); +trace_netif_rx_exit (ret); +if (need_bh_off) +local_bh_enable ();return ret; }EXPORT_SYMBOL (netif_rx);