6.5.4-rc1 review
Subsystems (6)
Greg Kroah-Hartman
maintainerPATCH 122/285 net: annotate data-races around sk->sk_tsflags
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit e3390b30a5dfb112e8e802a59c0f68f947b638b2 ]
sk->sk_tsflags can be read locklessly, add corresponding annotations.
--- include/net/ip.h | 2 +- include/net/sock.h | 17 ++++++++++------- net/can/j1939/socket.c | 10 ++++++---- net/core/skbuff.c | 10 ++++++---- net/core/sock.c | 4 ++-- net/ipv4/ip_output.c | 2 +- net/ipv4/ip_sockglue.c | 2 +- net/ipv4/tcp.c | 4 ++-- net/ipv6/ip6_output.c | 2 +- net/ipv6/ping.c | 2 +- net/ipv6/raw.c | 2 +- net/ipv6/udp.c | 2 +- net/socket.c | 13 +++++++------ 13 files changed, 40 insertions(+), 32 deletions(-)
include/net/ip.h +1 -1
@@ -94,7 +94,7 @@ static inline void ipcm_init_sk(struct ipcm_cookie *ipcm,ipcm_init (ipcm); ipcm->sockc.mark =READ_ONCE (inet->sk.sk_mark); - ipcm->sockc.tsflags = inet->sk.sk_tsflags; + ipcm->sockc.tsflags =READ_ONCE (inet->sk.sk_tsflags); ipcm->oif =READ_ONCE (inet->sk.sk_bound_dev_if); ipcm->addr = inet->inet_saddr; ipcm->protocol = inet->inet_num;
include/net/sock.h +10 -7
@@ -1906,7 +1906,9 @@ struct sockcm_cookie {static inline void sockcm_init (struct sockcm_cookie *sockc,const struct sock *sk) { - *sockc = (struct sockcm_cookie ) { .tsflags = sk->sk_tsflags }; + *sockc = (struct sockcm_cookie ) { + .tsflags =READ_ONCE (sk->sk_tsflags) + }; } int __sock_cmsg_send(struct sock *sk, struct cmsghdr *cmsg,
@@ -2701,9 +2703,9 @@ void __sock_recv_wifi_status(struct msghdr *msg, struct sock *sk,static inline void sock_recv_timestamp (struct msghdr *msg,struct sock *sk,struct sk_buff *skb) { -ktime_t kt = skb->tstamp;struct skb_shared_hwtstamps *hwtstamps =skb_hwtstamps (skb); - +u32 tsflags =READ_ONCE (sk->sk_tsflags); +ktime_t kt = skb->tstamp;/* * generate control messages if * - receive time stamping in software requested
@@ -2711,10 +2713,10 @@ sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb)* - hardware time stamps available and wanted */ if (sock_flag (sk,SOCK_RCVTSTAMP ) || - (sk->sk_tsflags &SOF_TIMESTAMPING_RX_SOFTWARE ) || - (kt && sk->sk_tsflags &SOF_TIMESTAMPING_SOFTWARE ) || + (tsflags &SOF_TIMESTAMPING_RX_SOFTWARE ) || + (kt && tsflags &SOF_TIMESTAMPING_SOFTWARE ) || (hwtstamps->hwtstamp && - (sk->sk_tsflags &SOF_TIMESTAMPING_RAW_HARDWARE ))) + (tsflags &SOF_TIMESTAMPING_RAW_HARDWARE )))__sock_recv_timestamp (msg, sk, skb);else sock_write_timestamp (sk, kt);
@@ -2736,7 +2738,8 @@ static inline void sock_recv_cmsgs(struct msghdr *msg, struct sock *sk,#define TSFLAGS_ANY (SOF_TIMESTAMPING_SOFTWARE | \ SOF_TIMESTAMPING_RAW_HARDWARE) -if (sk->sk_flags &FLAGS_RECV_CMSGS || sk->sk_tsflags &TSFLAGS_ANY ) +if (sk->sk_flags &FLAGS_RECV_CMSGS || +READ_ONCE (sk->sk_tsflags) &TSFLAGS_ANY )__sock_recv_cmsgs (msg, sk, skb);else if (unlikely (sock_flag (sk,SOCK_TIMESTAMP )))sock_write_timestamp (sk, skb->tstamp);
net/can/j1939/socket.c +6 -4
@@ -974,6 +974,7 @@ static void __j1939_sk_errqueue(struct j1939_session *session, struct sock *sk,struct sock_exterr_skb *serr;struct sk_buff *skb;char *state ="UNK" ; +u32 tsflags;int err; jsk =j1939_sk (sk);
@@ -981,13 +982,14 @@ static void __j1939_sk_errqueue(struct j1939_session *session, struct sock *sk,if (!(jsk->state &J1939_SOCK_ERRQUEUE ))return ; + tsflags =READ_ONCE (sk->sk_tsflags);switch (type) {case J1939_ERRQUEUE_TX_ACK : -if (!(sk->sk_tsflags &SOF_TIMESTAMPING_TX_ACK )) +if (!(tsflags &SOF_TIMESTAMPING_TX_ACK ))return ;break ;case J1939_ERRQUEUE_TX_SCHED : -if (!(sk->sk_tsflags &SOF_TIMESTAMPING_TX_SCHED )) +if (!(tsflags &SOF_TIMESTAMPING_TX_SCHED ))return ;break ;case J1939_ERRQUEUE_TX_ABORT :
@@ -997,7 +999,7 @@ static void __j1939_sk_errqueue(struct j1939_session *session, struct sock *sk,case J1939_ERRQUEUE_RX_DPO : fallthrough;case J1939_ERRQUEUE_RX_ABORT : -if (!(sk->sk_tsflags &SOF_TIMESTAMPING_RX_SOFTWARE )) +if (!(tsflags &SOF_TIMESTAMPING_RX_SOFTWARE ))return ;break ;default :
@@ -1054,7 +1056,7 @@ static void __j1939_sk_errqueue(struct j1939_session *session, struct sock *sk, } serr->opt_stats = true; -if (sk->sk_tsflags &SOF_TIMESTAMPING_OPT_ID ) +if (tsflags &SOF_TIMESTAMPING_OPT_ID ) serr->ee.ee_data = session->tskey; netdev_dbg(session->priv->ndev, "%s: 0x%p tskey: %i, state: %s\n",
net/core/skbuff.c +6 -4
@@ -5149,7 +5149,7 @@ static void __skb_complete_tx_timestamp(struct sk_buff *skb, serr->ee.ee_info = tstype; serr->opt_stats = opt_stats; serr->header.h4.iif = skb->dev ? skb->dev->ifindex :0 ; -if (sk->sk_tsflags &SOF_TIMESTAMPING_OPT_ID ) { +if (READ_ONCE (sk->sk_tsflags) &SOF_TIMESTAMPING_OPT_ID ) { serr->ee.ee_data =skb_shinfo (skb)->tskey;if (sk_is_tcp (sk)) serr->ee.ee_data -=atomic_read (&sk->sk_tskey);
@@ -5205,21 +5205,23 @@ void __skb_tstamp_tx(struct sk_buff *orig_skb, {struct sk_buff *skb;bool tsonly, opt_stats = false; +u32 tsflags;if (!sk)return ; -if (!hwtstamps && !(sk->sk_tsflags &SOF_TIMESTAMPING_OPT_TX_SWHW ) && + tsflags =READ_ONCE (sk->sk_tsflags); +if (!hwtstamps && !(tsflags &SOF_TIMESTAMPING_OPT_TX_SWHW ) &&skb_shinfo (orig_skb)->tx_flags &SKBTX_IN_PROGRESS )return ; - tsonly = sk->sk_tsflags &SOF_TIMESTAMPING_OPT_TSONLY ; + tsonly = tsflags &SOF_TIMESTAMPING_OPT_TSONLY ;if (!skb_may_tx_timestamp (sk, tsonly))return ;if (tsonly) {#ifdef CONFIG_INET -if ((sk->sk_tsflags &SOF_TIMESTAMPING_OPT_STATS ) && +if ((tsflags &SOF_TIMESTAMPING_OPT_STATS ) &&sk_is_tcp (sk)) { skb =tcp_get_timestamping_opt_stats (sk, orig_skb, ack_skb);
net/core/sock.c +2 -2
@@ -937,7 +937,7 @@ int sock_set_timestamping(struct sock *sk, int optname,return ret; } - sk->sk_tsflags = val; +WRITE_ONCE (sk->sk_tsflags, val);sock_valbool_flag (sk,SOCK_TSTAMP_NEW , optname ==SO_TIMESTAMPING_NEW );if (val &SOF_TIMESTAMPING_RX_SOFTWARE )
@@ -1718,7 +1718,7 @@ int sk_getsockopt(struct sock *sk, int level, int optname,case SO_TIMESTAMPING_OLD : lv =sizeof (v.timestamping); - v.timestamping.flags = sk->sk_tsflags; + v.timestamping.flags =READ_ONCE (sk->sk_tsflags); v.timestamping.bind_phc = sk->sk_bind_phc;break ;
net/ipv4/ip_output.c +1 -1
@@ -982,7 +982,7 @@ static int __ip_append_data(struct sock *sk, paged = !!cork->gso_size;if (cork->tx_flags &SKBTX_ANY_TSTAMP && - sk->sk_tsflags &SOF_TIMESTAMPING_OPT_ID ) +READ_ONCE (sk->sk_tsflags) &SOF_TIMESTAMPING_OPT_ID ) tskey =atomic_inc_return (&sk->sk_tskey) -1 ; hh_len =LL_RESERVED_SPACE (rt->dst.dev);
net/ipv4/ip_sockglue.c +1 -1
@@ -510,7 +510,7 @@ static bool ipv4_datagram_support_cmsg(const struct sock *sk,* or without payload (SOF_TIMESTAMPING_OPT_TSONLY). */ info =PKTINFO_SKB_CB (skb); -if (!(sk->sk_tsflags &SOF_TIMESTAMPING_OPT_CMSG ) || +if (!(READ_ONCE (sk->sk_tsflags) &SOF_TIMESTAMPING_OPT_CMSG ) || !info->ipi_ifindex)return false;
net/ipv4/tcp.c +2 -2
@@ -2256,14 +2256,14 @@ void tcp_recv_timestamp(struct msghdr *msg, const struct sock *sk, } } -if (sk->sk_tsflags &SOF_TIMESTAMPING_SOFTWARE ) +if (READ_ONCE (sk->sk_tsflags) &SOF_TIMESTAMPING_SOFTWARE ) has_timestamping = true;else tss->ts[0 ] = (struct timespec64 ) {0 }; }if (tss->ts[2 ].tv_sec || tss->ts[2 ].tv_nsec) { -if (sk->sk_tsflags &SOF_TIMESTAMPING_RAW_HARDWARE ) +if (READ_ONCE (sk->sk_tsflags) &SOF_TIMESTAMPING_RAW_HARDWARE ) has_timestamping = true;else tss->ts[2 ] = (struct timespec64 ) {0 };
net/ipv6/ip6_output.c +1 -1
@@ -1502,7 +1502,7 @@ static int __ip6_append_data(struct sock *sk, orig_mtu = mtu;if (cork->tx_flags &SKBTX_ANY_TSTAMP && - sk->sk_tsflags &SOF_TIMESTAMPING_OPT_ID ) +READ_ONCE (sk->sk_tsflags) &SOF_TIMESTAMPING_OPT_ID ) tskey =atomic_inc_return (&sk->sk_tskey) -1 ; hh_len =LL_RESERVED_SPACE (rt->dst.dev);
net/ipv6/ping.c +1 -1
@@ -119,7 +119,7 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)return -EINVAL ;ipcm6_init_sk (&ipc6, np); - ipc6.sockc.tsflags = sk->sk_tsflags; + ipc6.sockc.tsflags =READ_ONCE (sk->sk_tsflags); ipc6.sockc.mark =READ_ONCE (sk->sk_mark); fl6.flowi6_oif = oif;
net/ipv6/raw.c +1 -1
@@ -778,7 +778,7 @@ static int rawv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len) fl6.flowi6_uid = sk->sk_uid;ipcm6_init (&ipc6); - ipc6.sockc.tsflags = sk->sk_tsflags; + ipc6.sockc.tsflags =READ_ONCE (sk->sk_tsflags); ipc6.sockc.mark = fl6.flowi6_mark;if (sin6) {
net/ipv6/udp.c +1 -1
@@ -1368,7 +1368,7 @@ int udpv6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)ipcm6_init (&ipc6); ipc6.gso_size =READ_ONCE (up->gso_size); - ipc6.sockc.tsflags = sk->sk_tsflags; + ipc6.sockc.tsflags =READ_ONCE (sk->sk_tsflags); ipc6.sockc.mark =READ_ONCE (sk->sk_mark);/* destination address check */
net/socket.c +7 -6
@@ -821,7 +821,7 @@ static bool skb_is_swtx_tstamp(const struct sk_buff *skb, int false_tstamp)static ktime_t get_timestamp (struct sock *sk,struct sk_buff *skb,int *if_index) { -bool cycles = sk->sk_tsflags &SOF_TIMESTAMPING_BIND_PHC ; +bool cycles =READ_ONCE (sk->sk_tsflags) &SOF_TIMESTAMPING_BIND_PHC ;struct skb_shared_hwtstamps *shhwtstamps =skb_hwtstamps (skb);struct net_device *orig_dev;ktime_t hwtstamp;
@@ -873,12 +873,12 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,int need_software_tstamp =sock_flag (sk,SOCK_RCVTSTAMP );int new_tstamp =sock_flag (sk,SOCK_TSTAMP_NEW );struct scm_timestamping_internal tss; -int empty =1 , false_tstamp =0 ;struct skb_shared_hwtstamps *shhwtstamps =skb_hwtstamps (skb);int if_index;ktime_t hwtstamp; +u32 tsflags;/* Race occurred between timestamp enabling and packet receiving. Fill in the current time for now. */
@@ -920,11 +920,12 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk, }memset (&tss,0 ,sizeof (tss)); -if ((sk->sk_tsflags &SOF_TIMESTAMPING_SOFTWARE ) && + tsflags =READ_ONCE (sk->sk_tsflags); +if ((tsflags &SOF_TIMESTAMPING_SOFTWARE ) &&ktime_to_timespec64_cond (skb->tstamp, tss.ts +0 )) empty =0 ;if (shhwtstamps && - (sk->sk_tsflags &SOF_TIMESTAMPING_RAW_HARDWARE ) && + (tsflags &SOF_TIMESTAMPING_RAW_HARDWARE ) && !skb_is_swtx_tstamp (skb, false_tstamp)) { if_index =0 ;if (skb_shinfo (skb)->tx_flags &SKBTX_HW_TSTAMP_NETDEV )
@@ -932,14 +933,14 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,else hwtstamp = shhwtstamps->hwtstamp; -if (sk->sk_tsflags &SOF_TIMESTAMPING_BIND_PHC ) +if (tsflags &SOF_TIMESTAMPING_BIND_PHC ) hwtstamp =ptp_convert_timestamp (&hwtstamp, sk->sk_bind_phc);if (ktime_to_timespec64_cond (hwtstamp, tss.ts +2 )) { empty =0 ; -if ((sk->sk_tsflags &SOF_TIMESTAMPING_OPT_PKTINFO ) && +if ((tsflags &SOF_TIMESTAMPING_OPT_PKTINFO ) && !skb_is_err_queue (skb))put_ts_pktinfo (msg, skb, if_index); }
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 123/285 net: annotate data-races around sk->sk_bind_phc
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 251cd405a9e6e70b92fe5afbdd17fd5caf9d3266 ]
sk->sk_bind_phc is read locklessly. Add corresponding annotations.
--- net/core/sock.c | 4 ++-- net/socket.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-)
net/core/sock.c +2 -2
@@ -894,7 +894,7 @@ static int sock_timestamping_bind_phc(struct sock *sk, int phc_index)if (!match)return -EINVAL ; - sk->sk_bind_phc = phc_index; +WRITE_ONCE (sk->sk_bind_phc, phc_index);return 0 ; }
@@ -1719,7 +1719,7 @@ int sk_getsockopt(struct sock *sk, int level, int optname,case SO_TIMESTAMPING_OLD : lv =sizeof (v.timestamping); v.timestamping.flags =READ_ONCE (sk->sk_tsflags); - v.timestamping.bind_phc = sk->sk_bind_phc; + v.timestamping.bind_phc =READ_ONCE (sk->sk_bind_phc);break ;case SO_RCVTIMEO_OLD :
net/socket.c +1 -1
@@ -935,7 +935,7 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,if (tsflags &SOF_TIMESTAMPING_BIND_PHC ) hwtstamp =ptp_convert_timestamp (&hwtstamp, - sk->sk_bind_phc); +READ_ONCE (sk->sk_bind_phc));if (ktime_to_timespec64_cond (hwtstamp, tss.ts +2 )) { empty =0 ;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 124/285 ipv4: ignore dst hint for multipath routes
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sriram Yagnaraman <[email protected]>
[ Upstream commit 6ac66cb03ae306c2e288a9be18226310529f5b25 ]
Route hints when the nexthop is part of a multipath group causes packets in the same receive batch to be sent to the same nexthop irrespective of the multipath hash of the packet. So, do not extract route hint for packets whose destination is part of a multipath group.
A new SKB flag IPSKB_MULTIPATH is introduced for this purpose, set the flag when route is looked up in ip_mkroute_input() and use it in ip_extract_route_hint() to check for the existence of the flag.
--- include/net/ip.h | 1 + net/ipv4/ip_input.c | 3 ++- net/ipv4/route.c | 1 + 3 files changed, 4 insertions(+), 1 deletion(-)
include/net/ip.h +1 -0
@@ -57,6 +57,7 @@ struct inet_skb_parm {#define IPSKB_FRAG_PMTU BIT(6)#define IPSKB_L3SLAVE BIT(7)#define IPSKB_NOPOLICY BIT(8) +#define IPSKB_MULTIPATH BIT(9)u16 frag_max_size; };
net/ipv4/ip_input.c +2 -1
@@ -584,7 +584,8 @@ static void ip_sublist_rcv_finish(struct list_head *head)static struct sk_buff *ip_extract_route_hint (const struct net *net,struct sk_buff *skb,int rt_type) { -if (fib4_has_custom_rules (net) || rt_type ==RTN_BROADCAST ) +if (fib4_has_custom_rules (net) || rt_type ==RTN_BROADCAST || +IPCB (skb)->flags &IPSKB_MULTIPATH )return NULL ;return skb;
net/ipv4/route.c +1 -0
@@ -2144,6 +2144,7 @@ static int ip_mkroute_input(struct sk_buff *skb,int h =fib_multipath_hash (res->fi->fib_net,NULL , skb, hkeys);fib_select_multipath (res, h); + IPCB(skb)->flags |= IPSKB_MULTIPATH; }#endif
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 125/285 ipv6: ignore dst hint for multipath routes
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sriram Yagnaraman <[email protected]>
[ Upstream commit 8423be8926aa82cd2e28bba5cc96ccb72c7ce6be ]
Route hints when the nexthop is part of a multipath group causes packets in the same receive batch to be sent to the same nexthop irrespective of the multipath hash of the packet. So, do not extract route hint for packets whose destination is part of a multipath group.
A new SKB flag IP6SKB_MULTIPATH is introduced for this purpose, set the flag when route is looked up in fib6_select_path() and use it in ip6_can_use_hint() to check for the existence of the flag.
--- include/linux/ipv6.h | 1 + net/ipv6/ip6_input.c | 3 ++- net/ipv6/route.c | 3 +++ 3 files changed, 6 insertions(+), 1 deletion(-)
include/linux/ipv6.h +1 -0
@@ -146,6 +146,7 @@ struct inet6_skb_parm {#define IP6SKB_JUMBOGRAM 128#define IP6SKB_SEG6 256#define IP6SKB_FAKEJUMBO 512 +#define IP6SKB_MULTIPATH 1024 };#if defined(CONFIG_NET_L3_MASTER_DEV )
net/ipv6/ip6_input.c +2 -1
@@ -99,7 +99,8 @@ static bool ip6_can_use_hint(const struct sk_buff *skb,static struct sk_buff *ip6_extract_route_hint (const struct net *net,struct sk_buff *skb) { -if (fib6_routes_require_src (net) ||fib6_has_custom_rules (net)) +if (fib6_routes_require_src (net) ||fib6_has_custom_rules (net) || +IP6CB (skb)->flags &IP6SKB_MULTIPATH )return NULL ;return skb;
net/ipv6/route.c +3 -0
@@ -424,6 +424,9 @@ void fib6_select_path(const struct net *net, struct fib6_result *res,if (match->nh && have_oif_match && res->nh)return ; +if (skb) +IP6CB (skb)->flags |=IP6SKB_MULTIPATH ; +/* We might have already computed the hash for ICMPv6 errors. In such * case it will always be non-zero. Otherwise now is the time to do it. */
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 126/285 selftests/bpf: Fix a CI failure caused by vsock write
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xu Kuohai <[email protected]>
[ Upstream commit c1970e26bdc1209974bb5cf31cc23f2b7ad6ce50 ]
While commit 90f0074cd9f9 ("selftests/bpf: fix a CI failure caused by vsock sockmap test") fixes a receive failure of vsock sockmap test, there is still a write failure:
Error: #211/79 sockmap_listen/sockmap VSOCK test_vsock_redir
Error: #211/79 sockmap_listen/sockmap VSOCK test_vsock_redir
./test_progs:vsock_unix_redir_connectible:1501: egress: write: Transport endpoint is not connected vsock_unix_redir_connectible:FAIL:1501 ./test_progs:vsock_unix_redir_connectible:1501: ingress: write: Transport endpoint is not connected vsock_unix_redir_connectible:FAIL:1501 ./test_progs:vsock_unix_redir_connectible:1501: egress: write: Transport endpoint is not connected vsock_unix_redir_connectible:FAIL:1501
The reason is that the vsock connection in the test is set to ESTABLISHED state by function virtio_transport_recv_pkt, which is executed in a workqueue thread, so when the user space test thread runs before the workqueue thread, this problem occurs.
To fix it, before writing the connection, wait for it to be connected.
--- .../bpf/prog_tests/sockmap_helpers.h | 26 +++++++++++++++++++ .../selftests/bpf/prog_tests/sockmap_listen.c | 7 +++++ 2 files changed, 33 insertions(+)
tools/testing/selftests/bpf/prog_tests/sockmap_helpers.h +26 -0
@@ -179,6 +179,32 @@ __ret; \ }) +static inline int poll_connect (int fd,unsigned int timeout_sec) +{ +struct timeval timeout = { .tv_sec = timeout_sec }; +fd_set wfds; +int r, eval; +socklen_t esize =sizeof (eval); + +FD_ZERO (&wfds); +FD_SET (fd, &wfds); + + r =select (fd +1 ,NULL , &wfds,NULL , &timeout); +if (r ==0 ) + errno =ETIME ; +if (r !=1 ) +return -1 ; + +if (getsockopt (fd,SOL_SOCKET ,SO_ERROR , &eval, &esize) <0 ) +return -1 ; +if (eval !=0 ) { + errno = eval; +return -1 ; + } + +return 0 ; +} +static inline int poll_read (int fd,unsigned int timeout_sec) {struct timeval timeout = { .tv_sec = timeout_sec };
tools/testing/selftests/bpf/prog_tests/sockmap_listen.c +7 -0
@@ -1452,11 +1452,18 @@ static int vsock_socketpair_connectible(int sotype, int *v0, int *v1)if (p <0 ) goto close_cli; +if (poll_connect (c,IO_TIMEOUT_SEC ) <0 ) { +FAIL_ERRNO ("poll_connect" ); + goto close_acc; + } + *v0 = p; *v1 = c;return 0 ; +close_acc: +close (p); close_cli:close (c); close_srv:
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 127/285 igb: disable virtualization features on 82580
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Corinna Vinschen <[email protected]>
[ Upstream commit fa09bc40b21a33937872c4c4cf0f266ec9fa4869 ]
Disable virtualization features on 82580 just as on i210/i211. This avoids that virt functions are acidentally called on 82850.
--- drivers/net/ethernet/intel/igb/igb_main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/net/ethernet/intel/igb/igb_main.c +3 -2
@@ -3933,8 +3933,9 @@ static void igb_probe_vfs(struct igb_adapter *adapter)struct pci_dev *pdev = adapter->pdev;struct e1000_hw *hw = &adapter->hw; -/* Virtualization features not supported on i210 family. */ -if ((hw->mac.type == e1000_i210) || (hw->mac.type == e1000_i211)) +/* Virtualization features not supported on i210 and 82580 family. */ +if ((hw->mac.type == e1000_i210) || (hw->mac.type == e1000_i211) || + (hw->mac.type == e1000_82580))return ;/* Of the below we really only want the effect of getting
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 128/285 gve: fix frag_list chaining
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 817c7cd2043a83a3d8147f40eea1505ac7300b62 ]
gve_rx_append_frags() is able to build skbs chained with frag_list, like GRO engine.
Problem is that shinfo->frag_list should only be used for the head of the chain.
All other links should use skb->next pointer.
Otherwise, built skbs are not valid and can cause crashes.
Equivalent code in GRO (skb_gro_receive()) is:
if (NAPI_GRO_CB(p)->last == p)
skb_shinfo(p)->frag_list = skb;
else
NAPI_GRO_CB(p)->last->next = skb;
NAPI_GRO_CB(p)->last = skb;--- drivers/net/ethernet/google/gve/gve_rx_dqo.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/net/ethernet/google/gve/gve_rx_dqo.c +4 -1
@@ -492,7 +492,10 @@ static int gve_rx_append_frags(struct napi_struct *napi,if (!skb)return -1 ; -skb_shinfo (rx->ctx.skb_tail)->frag_list = skb; +if (rx->ctx.skb_tail == rx->ctx.skb_head) +skb_shinfo (rx->ctx.skb_head)->frag_list = skb; +else + rx->ctx.skb_tail->next = skb; rx->ctx.skb_tail = skb; num_frags =0 ; }
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 129/285 veth: Fixing transmit return status for dropped packets
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Liang Chen <[email protected]>
[ Upstream commit 151e887d8ff97e2e42110ffa1fb1e6a2128fb364 ]
The veth_xmit function returns NETDEV_TX_OK even when packets are dropped. This behavior leads to incorrect calculations of statistics counts, as well as things like txq->trans_start updates.
--- drivers/net/veth.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/net/veth.c +3 -1
@@ -344,6 +344,7 @@ static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev) {struct veth_priv *rcv_priv, *priv =netdev_priv (dev);struct veth_rq *rq =NULL ; +int ret =NETDEV_TX_OK ;struct net_device *rcv;int length = skb->len;bool use_napi = false;
@@ -376,6 +377,7 @@ static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev) }else { drop:atomic64_inc (&priv->dropped); + ret =NET_XMIT_DROP ; }if (use_napi)
@@ -383,7 +385,7 @@ static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev)rcu_read_unlock (); -return NETDEV_TX_OK ; +return ret; }static u64 veth_stats_tx (struct net_device *dev,u64 *packets,u64 *bytes)
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 130/285 net: ipv6/addrconf: avoid integer underflow in ipv6_create_tempaddr
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Henrie <[email protected]>
[ Upstream commit f31867d0d9d82af757c1e0178b659438f4c1ea3c ]
The existing code incorrectly casted a negative value (the result of a subtraction) to an unsigned value without checking. For example, if /proc/sys/net/ipv6/conf/*/temp_prefered_lft was set to 1, the preferred lifetime would jump to 4 billion seconds. On my machine and network the shortest lifetime that avoided underflow was 3 seconds.
--- net/ipv6/addrconf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/ipv6/addrconf.c +1 -1
@@ -1368,7 +1368,7 @@ static int ipv6_create_tempaddr(struct inet6_ifaddr *ifp, bool block)* idev->desync_factor if it's larger */ cnf_temp_preferred_lft =READ_ONCE (idev->cnf.temp_prefered_lft); - max_desync_factor =min_t (__u32, + max_desync_factor =min_t (long, idev->cnf.max_desync_factor, cnf_temp_preferred_lft - regen_advance);
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 131/285 net: phy: micrel: Correct bit assignments for phy_device flags
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oleksij Rempel <[email protected]>
[ Upstream commit 719c5e37e99d2fd588d1c994284d17650a66354c ]
Previously, the defines for phy_device flags in the Micrel driver were ambiguous in their representation. They were intended to be bit masks but were mistakenly defined as bit positions. This led to the following issues:
- MICREL_KSZ8_P1_ERRATA, designated for KSZ88xx switches, overlapped with MICREL_PHY_FXEN and MICREL_PHY_50MHZ_CLK.
- Due to this overlap, the code path for MICREL_PHY_FXEN, tailored for the KSZ8041 PHY, was not executed for KSZ88xx PHYs.
- Similarly, the code associated with MICREL_PHY_50MHZ_CLK wasn't triggered for KSZ88xx.
To rectify this, all three flags have now been explicitly converted to use the BIT() macro, ensuring they are defined as bit masks and preventing potential overlaps in the future.
--- include/linux/micrel_phy.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
include/linux/micrel_phy.h +3 -3
@@ -41,9 +41,9 @@#define PHY_ID_KSZ9477 0x00221631/* struct phy_device dev_flags definitions */ -#define MICREL_PHY_50MHZ_CLK 0x00000001 -#define MICREL_PHY_FXEN 0x00000002 -#define MICREL_KSZ8_P1_ERRATA 0x00000003 +#define MICREL_PHY_50MHZ_CLK BIT(0) +#define MICREL_PHY_FXEN BIT(1) +#define MICREL_KSZ8_P1_ERRATA BIT(2)#define MICREL_KSZ9021_EXTREG_CTRL 0xB#define MICREL_KSZ9021_EXTREG_DATA_WRITE 0xC
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 132/285 bpf, sockmap: Fix skb refcnt race after locking changes
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: John Fastabend <[email protected]>
[ Upstream commit a454d84ee20baf7bd7be90721b9821f73c7d23d9 ]
There is a race where skb's from the sk_psock_backlog can be referenced after userspace side has already skb_consumed() the sk_buff and its refcnt dropped to zer0 causing use after free.
The flow is the following:
while ((skb = skb_peek(&psock->ingress_skb))
sk_psock_handle_Skb(psock, skb, ..., ingress)
if (!ingress) ...
sk_psock_skb_ingress
sk_psock_skb_ingress_enqueue(skb)
msg->skb = skb
sk_psock_queue_msg(psock, msg)
skb_dequeue(&psock->ingress_skb)The sk_psock_queue_msg() puts the msg on the ingress_msg queue. This is what the application reads when recvmsg() is called. An application can read this anytime after the msg is placed on the queue. The recvmsg hook will also read msg->skb and then after user space reads the msg will call consume_skb(skb) on it effectively free'ing it.
But, the race is in above where backlog queue still has a reference to the skb and calls skb_dequeue(). If the skb_dequeue happens after the user reads and free's the skb we have a use after free.
The !ingress case does not suffer from this problem because it uses sendmsg_*(sk, msg) which does not pass the sk_buff further down the stack.
The following splat was observed with 'test_progs -t sockmap_listen':
[ 1022.710250][ T2556] general protection fault, ... [...] [ 1022.712830][ T2556] Workqueue: events sk_psock_backlog [ 1022.713262][ T2556] RIP: 0010:skb_dequeue+0x4c/0x80 [ 1022.713653][ T2556] Code: ... [...] [ 1022.720699][ T2556] Call Trace: [ 1022.720984][ T2556] <TASK> [ 1022.721254][ T2556] ? die_addr+0x32/0x80^M [ 1022.721589][ T2556] ? exc_general_protection+0x25a/0x4b0 [ 1022.722026][ T2556] ? asm_exc_general_protection+0x22/0x30 [ 1022.722489][ T2556] ? skb_dequeue+0x4c/0x80 [ 1022.722854][ T2556] sk_psock_backlog+0x27a/0x300 [ 1022.723243][ T2556] process_one_work+0x2a7/0x5b0 [ 1022.723633][ T2556] worker_thread+0x4f/0x3a0 [ 1022.723998][ T2556] ? __pfx_worker_thread+0x10/0x10 [ 1022.724386][ T2556] kthread+0xfd/0x130 [ 1022.724709][ T2556] ? __pfx_kthread+0x10/0x10 [ 1022.725066][ T2556] ret_from_fork+0x2d/0x50 [ 1022.725409][ T2556] ? __pfx_kthread+0x10/0x10 [ 1022.725799][ T2556] ret_from_fork_asm+0x1b/0x30 [ 1022.726201][ T2556] </TASK>
To fix we add an skb_get() before passing the skb to be enqueued in the engress queue. This bumps the skb->users refcnt so that consume_skb() and kfree_skb will not immediately free the sk_buff. With this we can be sure the skb is still around when we do the dequeue. Then we just need to decrement the refcnt or free the skb in the backlog case which we do by calling kfree_skb() on the ingress case as well as the sendmsg case.
Before locking change from fixes tag we had the sock locked so we couldn't race with user and there was no issue here.
--- net/core/skmsg.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
net/core/skmsg.c +8 -4
@@ -612,12 +612,18 @@ static int sk_psock_skb_ingress_self(struct sk_psock *psock, struct sk_buff *skbstatic int sk_psock_handle_skb (struct sk_psock *psock,struct sk_buff *skb,u32 off,u32 len,bool ingress) { +int err =0 ; +if (!ingress) {if (!sock_writeable (psock->sk))return -EAGAIN ;return skb_send_sock (psock->sk, skb, off, len); } -return sk_psock_skb_ingress (psock, skb, off, len); +skb_get (skb); + err =sk_psock_skb_ingress (psock, skb, off, len); +if (err <0 ) +kfree_skb (skb); +return err; } static void sk_psock_skb_state(struct sk_psock *psock,
@@ -685,9 +691,7 @@ static void sk_psock_backlog(struct work_struct *work) }while (len); skb =skb_dequeue (&psock->ingress_skb); -if (!ingress) { -kfree_skb (skb); - } +kfree_skb (skb); } end:mutex_unlock (&psock->work_mutex);
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 133/285 af_unix: Fix msg_controllen test in scm_pidfd_recv() for MSG_CMSG_COMPAT.
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
[ Upstream commit 718e6b51298e0f254baca0d40ab52a00e004e014 ]
Heiko Carstens reported that SCM_PIDFD does not work with MSG_CMSG_COMPAT because scm_pidfd_recv() always checks msg_controllen against sizeof(struct cmsghdr).
We need to use sizeof(struct compat_cmsghdr) for the compat case.
--- include/net/scm.h | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-)
include/net/scm.h +9 -5
@@ -9,6 +9,7 @@#include <linux/pid.h> #include <linux/nsproxy.h> #include <linux/sched/signal.h> +#include <net/compat.h> /* Well, we should have at least one descriptor open * to accept passed FDs 8)
@@ -123,14 +124,17 @@ static inline bool scm_has_secdata(struct socket *sock)static __inline__void scm_pidfd_recv (struct msghdr *msg,struct scm_cookie *scm) {struct file *pidfd_file =NULL ; -int pidfd; +int len, pidfd; -/* -* put_cmsg() doesn't return an error if CMSG is truncated, +/* put_cmsg() doesn't return an error if CMSG is truncated, * that's why we need to opencode these checks here. */ -if ((msg->msg_controllen <=sizeof (struct cmsghdr )) || - (msg->msg_controllen -sizeof (struct cmsghdr )) <sizeof (int )) { +if (msg->msg_flags &MSG_CMSG_COMPAT ) + len =sizeof (struct compat_cmsghdr ) +sizeof (int ); +else + len =sizeof (struct cmsghdr ) +sizeof (int ); + +if (msg->msg_controllen < len) { msg->msg_flags |=MSG_CTRUNC ;return ; }
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 134/285 af_unix: Fix data-races around user->unix_inflight.
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
[ Upstream commit 0bc36c0650b21df36fbec8136add83936eaf0607 ]
user->unix_inflight is changed under spin_lock(unix_gc_lock), but too_many_unix_fds() reads it locklessly.
Let's annotate the write/read accesses to user->unix_inflight.
BUG: KCSAN: data-race in unix_attach_fds / unix_inflight
write to 0xffffffff8546f2d0 of 8 bytes by task 44798 on cpu 1:
unix_inflight+0x157/0x180 net/unix/scm.c:66 unix_attach_fds+0x147/0x1e0 net/unix/scm.c:123 unix_scm_to_skb net/unix/af_unix.c:1827 [inline] unix_dgram_sendmsg+0x46a/0x14f0 net/unix/af_unix.c:1950 unix_seqpacket_sendmsg net/unix/af_unix.c:2308 [inline] unix_seqpacket_sendmsg+0xba/0x130 net/unix/af_unix.c:2292 sock_sendmsg_nosec net/socket.c:725 [inline] sock_sendmsg+0x148/0x160 net/socket.c:748 ____sys_sendmsg+0x4e4/0x610 net/socket.c:2494 ___sys_sendmsg+0xc6/0x140 net/socket.c:2548 __sys_sendmsg+0x94/0x140 net/socket.c:2577 __do_sys_sendmsg net/socket.c:2586 [inline] __se_sys_sendmsg net/socket.c:2584 [inline] __x64_sys_sendmsg+0x45/0x50 net/socket.c:2584 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3b/0x90 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x6e/0xd8
read to 0xffffffff8546f2d0 of 8 bytes by task 44814 on cpu 0:
too_many_unix_fds net/unix/scm.c:101 [inline] unix_attach_fds+0x54/0x1e0 net/unix/scm.c:110 unix_scm_to_skb net/unix/af_unix.c:1827 [inline] unix_dgram_sendmsg+0x46a/0x14f0 net/unix/af_unix.c:1950 unix_seqpacket_sendmsg net/unix/af_unix.c:2308 [inline] unix_seqpacket_sendmsg+0xba/0x130 net/unix/af_unix.c:2292 sock_sendmsg_nosec net/socket.c:725 [inline] sock_sendmsg+0x148/0x160 net/socket.c:748 ____sys_sendmsg+0x4e4/0x610 net/socket.c:2494 ___sys_sendmsg+0xc6/0x140 net/socket.c:2548 __sys_sendmsg+0x94/0x140 net/socket.c:2577 __do_sys_sendmsg net/socket.c:2586 [inline] __se_sys_sendmsg net/socket.c:2584 [inline] __x64_sys_sendmsg+0x45/0x50 net/socket.c:2584 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3b/0x90 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x6e/0xd8
value changed: 0x000000000000000c -> 0x000000000000000d
Reported by Kernel Concurrency Sanitizer on:
CPU: 0 PID: 44814 Comm: systemd-coredum Not tainted 6.4.0-11989-g6843306689af #6 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014
--- net/unix/scm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
net/unix/scm.c +3 -3
@@ -63,7 +63,7 @@ void unix_inflight(struct user_struct *user, struct file *fp)/* Paired with READ_ONCE() in wait_for_unix_gc() */ WRITE_ONCE (unix_tot_inflight, unix_tot_inflight +1 ); } - user->unix_inflight++; +WRITE_ONCE (user->unix_inflight, user->unix_inflight +1 );spin_unlock (&unix_gc_lock); }
@@ -84,7 +84,7 @@ void unix_notinflight(struct user_struct *user, struct file *fp)/* Paired with READ_ONCE() in wait_for_unix_gc() */ WRITE_ONCE (unix_tot_inflight, unix_tot_inflight -1 ); } - user->unix_inflight--; +WRITE_ONCE (user->unix_inflight, user->unix_inflight -1 );spin_unlock (&unix_gc_lock); }
@@ -98,7 +98,7 @@ static inline bool too_many_unix_fds(struct task_struct *p) {struct user_struct *user =current_user (); -if (unlikely (user->unix_inflight >task_rlimit (p,RLIMIT_NOFILE ))) +if (unlikely (READ_ONCE (user->unix_inflight) >task_rlimit (p,RLIMIT_NOFILE )))return !capable (CAP_SYS_RESOURCE ) && !capable (CAP_SYS_ADMIN );return false; }
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 135/285 af_unix: Fix data-race around unix_tot_inflight.
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
[ Upstream commit ade32bd8a738d7497ffe9743c46728db26740f78 ]
unix_tot_inflight is changed under spin_lock(unix_gc_lock), but unix_release_sock() reads it locklessly.
Let's use READ_ONCE() for unix_tot_inflight.
Note that the writer side was marked by commit 9d6d7f1cb67c ("af_unix:
annote lockless accesses to unix_tot_inflight & gc_in_progress")
BUG: KCSAN: data-race in unix_inflight / unix_release_sock
write (marked) to 0xffffffff871852b8 of 4 bytes by task 123 on cpu 1:
unix_inflight+0x130/0x180 net/unix/scm.c:64 unix_attach_fds+0x137/0x1b0 net/unix/scm.c:123 unix_scm_to_skb net/unix/af_unix.c:1832 [inline] unix_dgram_sendmsg+0x46a/0x14f0 net/unix/af_unix.c:1955 sock_sendmsg_nosec net/socket.c:724 [inline] sock_sendmsg+0x148/0x160 net/socket.c:747 ____sys_sendmsg+0x4e4/0x610 net/socket.c:2493 ___sys_sendmsg+0xc6/0x140 net/socket.c:2547 __sys_sendmsg+0x94/0x140 net/socket.c:2576 __do_sys_sendmsg net/socket.c:2585 [inline] __se_sys_sendmsg net/socket.c:2583 [inline] __x64_sys_sendmsg+0x45/0x50 net/socket.c:2583 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3b/0x90 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x72/0xdc
read to 0xffffffff871852b8 of 4 bytes by task 4891 on cpu 0:
unix_release_sock+0x608/0x910 net/unix/af_unix.c:671 unix_release+0x59/0x80 net/unix/af_unix.c:1058 __sock_release+0x7d/0x170 net/socket.c:653 sock_close+0x19/0x30 net/socket.c:1385 __fput+0x179/0x5e0 fs/file_table.c:321 ____fput+0x15/0x20 fs/file_table.c:349 task_work_run+0x116/0x1a0 kernel/task_work.c:179 resume_user_mode_work include/linux/resume_user_mode.h:49 [inline] exit_to_user_mode_loop kernel/entry/common.c:171 [inline] exit_to_user_mode_prepare+0x174/0x180 kernel/entry/common.c:204 __syscall_exit_to_user_mode_work kernel/entry/common.c:286 [inline] syscall_exit_to_user_mode+0x1a/0x30 kernel/entry/common.c:297 do_syscall_64+0x4b/0x90 arch/x86/entry/common.c:86 entry_SYSCALL_64_after_hwframe+0x72/0xdc
value changed: 0x00000000 -> 0x00000001
Reported by Kernel Concurrency Sanitizer on:
CPU: 0 PID: 4891 Comm: systemd-coredum Not tainted 6.4.0-rc5-01219-gfa0e21fa4443 #5 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014
--- net/unix/af_unix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/unix/af_unix.c +1 -1
@@ -680,7 +680,7 @@ static void unix_release_sock(struct sock *sk, int embrion)* What the above comment does talk about? --ANK(980817) */ -if (unix_tot_inflight) +if (READ_ONCE (unix_tot_inflight))unix_gc ();/* Garbage collect fds */ }
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 136/285 af_unix: Fix data-races around sk->sk_shutdown.
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
[ Upstream commit afe8764f76346ba838d4f162883e23d2fcfaa90e ]
sk->sk_shutdown is changed under unix_state_lock(sk), but unix_dgram_sendmsg() calls two functions to read sk_shutdown locklessly.
sock_alloc_send_pskb
`- sock_wait_for_wmem
Let's use READ_ONCE() there.
Note that the writer side was marked by commit e1d09c2c2f57 ("af_unix:
Fix data races around sk->sk_shutdown.").
BUG: KCSAN: data-race in sock_alloc_send_pskb / unix_release_sock
write (marked) to 0xffff8880069af12c of 1 bytes by task 1 on cpu 1:
unix_release_sock+0x75c/0x910 net/unix/af_unix.c:631 unix_release+0x59/0x80 net/unix/af_unix.c:1053 __sock_release+0x7d/0x170 net/socket.c:654 sock_close+0x19/0x30 net/socket.c:1386 __fput+0x2a3/0x680 fs/file_table.c:384 ____fput+0x15/0x20 fs/file_table.c:412 task_work_run+0x116/0x1a0 kernel/task_work.c:179 resume_user_mode_work include/linux/resume_user_mode.h:49 [inline] exit_to_user_mode_loop kernel/entry/common.c:171 [inline] exit_to_user_mode_prepare+0x174/0x180 kernel/entry/common.c:204 __syscall_exit_to_user_mode_work kernel/entry/common.c:286 [inline] syscall_exit_to_user_mode+0x1a/0x30 kernel/entry/common.c:297 do_syscall_64+0x4b/0x90 arch/x86/entry/common.c:86 entry_SYSCALL_64_after_hwframe+0x6e/0xd8
read to 0xffff8880069af12c of 1 bytes by task 28650 on cpu 0:
sock_alloc_send_pskb+0xd2/0x620 net/core/sock.c:2767 unix_dgram_sendmsg+0x2f8/0x14f0 net/unix/af_unix.c:1944 unix_seqpacket_sendmsg net/unix/af_unix.c:2308 [inline] unix_seqpacket_sendmsg+0xba/0x130 net/unix/af_unix.c:2292 sock_sendmsg_nosec net/socket.c:725 [inline] sock_sendmsg+0x148/0x160 net/socket.c:748 ____sys_sendmsg+0x4e4/0x610 net/socket.c:2494 ___sys_sendmsg+0xc6/0x140 net/socket.c:2548 __sys_sendmsg+0x94/0x140 net/socket.c:2577 __do_sys_sendmsg net/socket.c:2586 [inline] __se_sys_sendmsg net/socket.c:2584 [inline] __x64_sys_sendmsg+0x45/0x50 net/socket.c:2584 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3b/0x90 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x6e/0xd8
value changed: 0x00 -> 0x03
Reported by Kernel Concurrency Sanitizer on:
CPU: 0 PID: 28650 Comm: systemd-coredum Not tainted 6.4.0-11989-g6843306689af #6 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014
--- net/core/sock.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
net/core/sock.c +2 -2
@@ -2746,7 +2746,7 @@ static long sock_wait_for_wmem(struct sock *sk, long timeo)prepare_to_wait (sk_sleep (sk), &wait,TASK_INTERRUPTIBLE );if (refcount_read (&sk->sk_wmem_alloc) <READ_ONCE (sk->sk_sndbuf))break ; -if (sk->sk_shutdown &SEND_SHUTDOWN ) +if (READ_ONCE (sk->sk_shutdown) &SEND_SHUTDOWN )break ;if (sk->sk_err)break ;
@@ -2776,7 +2776,7 @@ struct sk_buff *sock_alloc_send_pskb(struct sock *sk, unsigned long header_len, goto failure; err = -EPIPE ; -if (sk->sk_shutdown &SEND_SHUTDOWN ) +if (READ_ONCE (sk->sk_shutdown) &SEND_SHUTDOWN ) goto failure;if (sk_wmem_alloc_get (sk) <READ_ONCE (sk->sk_sndbuf))
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 137/285 af_unix: Fix data race around sk->sk_err.
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <[email protected]>
[ Upstream commit b192812905e4b134f7b7994b079eb647e9d2d37e ]
As with sk->sk_shutdown shown in the previous patch, sk->sk_err can be read locklessly by unix_dgram_sendmsg().
Let's use READ_ONCE() for sk_err as well.
Note that the writer side is marked by commit cc04410af7de ("af_unix:
annotate lockless accesses to sk->sk_err").
--- net/core/sock.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/core/sock.c +1 -1
@@ -2748,7 +2748,7 @@ static long sock_wait_for_wmem(struct sock *sk, long timeo)break ;if (READ_ONCE (sk->sk_shutdown) &SEND_SHUTDOWN )break ; -if (sk->sk_err) +if (READ_ONCE (sk->sk_err))break ; timeo =schedule_timeout (timeo); }
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 138/285 net: sched: sch_qfq: Fix UAF in qfq_dequeue()
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: valis <[email protected]>
[ Upstream commit 8fc134fee27f2263988ae38920bc03da416b03d8 ]
When the plug qdisc is used as a class of the qfq qdisc it could trigger a UAF. This issue can be reproduced with following commands:
tc qdisc add dev lo root handle 1: qfq
tc class add dev lo parent 1: classid 1:1 qfq weight 1 maxpkt 512 tc qdisc add dev lo parent 1:1 handle 2: plug
tc filter add dev lo parent 1: basic classid 1:1
ping -c1 127.0.0.1
and boom:
[ 285.353793] BUG: KASAN: slab-use-after-free in qfq_dequeue+0xa7/0x7f0 [ 285.354910] Read of size 4 at addr ffff8880bad312a8 by task ping/144 [ 285.355903] [ 285.356165] CPU: 1 PID: 144 Comm: ping Not tainted 6.5.0-rc3+ #4 [ 285.357112] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.14.0-2 04/01/2014 [ 285.358376] Call Trace: [ 285.358773] <IRQ> [ 285.359109] dump_stack_lvl+0x44/0x60 [ 285.359708] print_address_description.constprop.0+0x2c/0x3c0 [ 285.360611] kasan_report+0x10c/0x120 [ 285.361195] ? qfq_dequeue+0xa7/0x7f0 [ 285.361780] qfq_dequeue+0xa7/0x7f0 [ 285.362342] __qdisc_run+0xf1/0x970 [ 285.362903] net_tx_action+0x28e/0x460 [ 285.363502] __do_softirq+0x11b/0x3de [ 285.364097] do_softirq.part.0+0x72/0x90 [ 285.364721] </IRQ> [ 285.365072] <TASK> [ 285.365422] __local_bh_enable_ip+0x77/0x90 [ 285.366079] __dev_queue_xmit+0x95f/0x1550 [ 285.366732] ? __pfx_csum_and_copy_from_iter+0x10/0x10 [ 285.367526] ? __pfx___dev_queue_xmit+0x10/0x10 [ 285.368259] ? __build_skb_around+0x129/0x190 [ 285.368960] ? ip_generic_getfrag+0x12c/0x170 [ 285.369653] ? __pfx_ip_generic_getfrag+0x10/0x10 [ 285.370390] ? csum_partial+0x8/0x20 [ 285.370961] ? raw_getfrag+0xe5/0x140 [ 285.371559] ip_finish_output2+0x539/0xa40 [ 285.372222] ? __pfx_ip_finish_output2+0x10/0x10 [ 285.372954] ip_output+0x113/0x1e0 [ 285.373512] ? __pfx_ip_output+0x10/0x10 [ 285.374130] ? icmp_out_count+0x49/0x60 [ 285.374739] ? __pfx_ip_finish_output+0x10/0x10 [ 285.375457] ip_push_pending_frames+0xf3/0x100 [ 285.376173] raw_sendmsg+0xef5/0x12d0 [ 285.376760] ? do_syscall_64+0x40/0x90 [ 285.377359] ? __static_call_text_end+0x136578/0x136578 [ 285.378173] ? do_syscall_64+0x40/0x90 [ 285.378772] ? kasan_enable_current+0x11/0x20 [ 285.379469] ? __pfx_raw_sendmsg+0x10/0x10 [ 285.380137] ? __sock_create+0x13e/0x270 [ 285.380673] ? __sys_socket+0xf3/0x180 [ 285.381174] ? __x64_sys_socket+0x3d/0x50 [ 285.381725] ? entry_SYSCALL_64_after_hwframe+0x6e/0xd8 [ 285.382425] ? __rcu_read_unlock+0x48/0x70 [ 285.382975] ? ip4_datagram_release_cb+0xd8/0x380 [ 285.383608] ? __pfx_ip4_datagram_release_cb+0x10/0x10 [ 285.384295] ? preempt_count_sub+0x14/0xc0 [ 285.384844] ? __list_del_entry_valid+0x76/0x140 [ 285.385467] ? _raw_spin_lock_bh+0x87/0xe0 [ 285.386014] ? __pfx__raw_spin_lock_bh+0x10/0x10 [ 285.386645] ? release_sock+0xa0/0xd0 [ 285.387148] ? preempt_count_sub+0x14/0xc0 [ 285.387712] ? freeze_secondary_cpus+0x348/0x3c0 [ 285.388341] ? aa_sk_perm+0x177/0x390 [ 285.388856] ? __pfx_aa_sk_perm+0x10/0x10 [ 285.389441] ? check_stack_object+0x22/0x70 [ 285.390032] ? inet_send_prepare+0x2f/0x120 [ 285.390603] ? __pfx_inet_sendmsg+0x10/0x10 [ 285.391172] sock_sendmsg+0xcc/0xe0 [ 285.391667] __sys_sendto+0x190/0x230 [ 285.392168] ? __pfx___sys_sendto+0x10/0x10 [ 285.392727] ? kvm_clock_get_cycles+0x14/0x30 [ 285.393328] ? set_normalized_timespec64+0x57/0x70 [ 285.393980] ? _raw_spin_unlock_irq+0x1b/0x40 [ 285.394578] ? __x64_sys_clock_gettime+0x11c/0x160 [ 285.395225] ? __pfx___x64_sys_clock_gettime+0x10/0x10 [ 285.395908] ? _copy_to_user+0x3e/0x60 [ 285.396432] ? exit_to_user_mode_prepare+0x1a/0x120 [ 285.397086] ? syscall_exit_to_user_mode+0x22/0x50 [ 285.397734] ? do_syscall_64+0x71/0x90 [ 285.398258] __x64_sys_sendto+0x74/0x90 [ 285.398786] do_syscall_64+0x64/0x90 [ 285.399273] ? exit_to_user_mode_prepare+0x1a/0x120 [ 285.399949] ? syscall_exit_to_user_mode+0x22/0x50 [ 285.400605] ? do_syscall_64+0x71/0x90 [ 285.401124] entry_SYSCALL_64_after_hwframe+0x6e/0xd8 [ 285.401807] RIP: 0033:0x495726 [ 285.402233] Code: ff ff ff f7 d8 64 89 02 48 c7 c0 ff ff ff ff eb b8 0f 1f 00 41 89 ca 64 8b 04 25 18 00 00 00 85 c0 75 11 b8 2c 00 00 00 0f 09 [ 285.404683] RSP: 002b:00007ffcc25fb618 EFLAGS: 00000246 ORIG_RAX: 000000000000002c [ 285.405677] RAX: ffffffffffffffda RBX: 0000000000000040 RCX: 0000000000495726 [ 285.406628] RDX: 0000000000000040 RSI: 0000000002518750 RDI: 0000000000000000 [ 285.407565] RBP: 00000000005205ef R08: 00000000005f8838 R09: 000000000000001c [ 285.408523] R10: 0000000000000000 R11: 0000000000000246 R12: 0000000002517634 [ 285.409460] R13: 00007ffcc25fb6f0 R14: 0000000000000003 R15: 0000000000000000 [ 285.410403] </TASK> [ 285.410704] [ 285.410929] Allocated by task 144: [ 285.411402] kasan_save_stack+0x1e/0x40 [ 285.411926] kasan_set_track+0x21/0x30 [ 285.412442] __kasan_slab_alloc+0x55/0x70 [ 285.412973] kmem_cache_alloc_node+0x187/0x3d0 [ 285.413567] __alloc_skb+0x1b4/0x230 [ 285.414060] __ip_append_data+0x17f7/0x1b60 [ 285.414633] ip_append_data+0x97/0xf0 [ 285.415144] raw_sendmsg+0x5a8/0x12d0 [ 285.415640] sock_sendmsg+0xcc/0xe0 [ 285.416117] __sys_sendto+0x190/0x230 [ 285.416626] __x64_sys_sendto+0x74/0x90 [ 285.417145] do_syscall_64+0x64/0x90 [ 285.417624] entry_SYSCALL_64_after_hwframe+0x6e/0xd8 [ 285.418306] [ 285.418531] Freed by task 144: [ 285.418960] kasan_save_stack+0x1e/0x40 [ 285.419469] kasan_set_track+0x21/0x30 [ 285.419988] kasan_save_free_info+0x27/0x40 [ 285.420556] ____kasan_slab_free+0x109/0x1a0 [ 285.421146] kmem_cache_free+0x1c2/0x450 [ 285.421680] __netif_receive_skb_core+0x2ce/0x1870 [ 285.422333] __netif_receive_skb_one_core+0x97/0x140 [ 285.423003] process_backlog+0x100/0x2f0 [ 285.423537] __napi_poll+0x5c/0x2d0 [ 285.424023] net_rx_action+0x2be/0x560 [ 285.424510] __do_softirq+0x11b/0x3de [ 285.425034] [ 285.425254] The buggy address belongs to the object at ffff8880bad31280 [ 285.425254] which belongs to the cache skbuff_head_cache of size 224 [ 285.426993] The buggy address is located 40 bytes inside of [ 285.426993] freed 224-byte region [ffff8880bad31280, ffff8880bad31360) [ 285.428572] [ 285.428798] The buggy address belongs to the physical page: [ 285.429540] page:00000000f4b77674 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0xbad31 [ 285.430758] flags: 0x100000000000200(slab|node=0|zone=1) [ 285.431447] page_type: 0xffffffff() [ 285.431934] raw: 0100000000000200 ffff88810094a8c0 dead000000000122 0000000000000000 [ 285.432757] raw: 0000000000000000 00000000800c000c 00000001ffffffff 0000000000000000 [ 285.433562] page dumped because: kasan: bad access detected [ 285.434144] [ 285.434320] Memory state around the buggy address: [ 285.434828] ffff8880bad31180: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 285.435580] ffff8880bad31200: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 285.436264] >ffff8880bad31280: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb [ 285.436777] ^ [ 285.437106] ffff8880bad31300: fb fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc [ 285.437616] ffff8880bad31380: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc [ 285.438126] ================================================================== [ 285.438662] Disabling lock debugging due to kernel taint
Fix this by:
1. Changing sch_plug's .peek handler to qdisc_peek_dequeued(), a function compatible with non-work-conserving qdiscs
2. Checking the return value of qdisc_dequeue_peeked() in sch_qfq.
--- net/sched/sch_plug.c | 2 +- net/sched/sch_qfq.c | 22 +++++++++++++++++----- 2 files changed, 18 insertions(+), 6 deletions(-)
net/sched/sch_plug.c +1 -1
@@ -207,7 +207,7 @@ static struct Qdisc_ops plug_qdisc_ops __read_mostly = { .priv_size = sizeof(struct plug_sched_data), .enqueue = plug_enqueue, .dequeue = plug_dequeue, - .peek = qdisc_peek_head, + .peek = qdisc_peek_dequeued, .init = plug_init, .change = plug_change, .reset = qdisc_reset_queue,
net/sched/sch_qfq.c +17 -5
@@ -974,10 +974,13 @@ static void qfq_update_eligible(struct qfq_sched *q) }/* Dequeue head packet of the head class in the DRR queue of the aggregate. */ -static void agg_dequeue (struct qfq_aggregate *agg, -struct qfq_class *cl,unsigned int len) +static struct sk_buff *agg_dequeue (struct qfq_aggregate *agg, +struct qfq_class *cl,unsigned int len) { -qdisc_dequeue_peeked (cl->qdisc); +struct sk_buff *skb =qdisc_dequeue_peeked (cl->qdisc); + +if (!skb) +return NULL ; cl->deficit -= (int ) len;
@@ -987,6 +990,8 @@ static void agg_dequeue(struct qfq_aggregate *agg, cl->deficit += agg->lmax;list_move_tail (&cl->alist, &agg->active); } + +return skb; } static inline struct sk_buff *qfq_peek_skb(struct qfq_aggregate *agg,
@@ -1132,11 +1137,18 @@ static struct sk_buff *qfq_dequeue(struct Qdisc *sch)if (!skb)return NULL ; -qdisc_qstats_backlog_dec (sch, skb); sch->q.qlen--; + + skb =agg_dequeue (in_serv_agg, cl, len); + +if (!skb) { + sch->q.qlen++; +return NULL ; + } + +qdisc_qstats_backlog_dec (sch, skb);qdisc_bstats_update (sch, skb); -agg_dequeue (in_serv_agg, cl, len);/* If lmax is lowered, through qfq_change_class, for a class * owning pending packets with larger size than the new value * of lmax, then the following condition may hold.
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 139/285 kcm: Destroy mutex in kcm_exit_net()
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shigeru Yoshida <[email protected]>
[ Upstream commit 6ad40b36cd3b04209e2d6c89d252c873d8082a59 ]
kcm_exit_net() should call mutex_destroy() on knet->mutex. This is especially needed if CONFIG_DEBUG_MUTEXES is enabled.
--- net/kcm/kcmsock.c | 2 ++ 1 file changed, 2 insertions(+)
net/kcm/kcmsock.c +2 -0
@@ -1859,6 +1859,8 @@ static __net_exit void kcm_exit_net(struct net *net)* that all multiplexors and psocks have been destroyed. */ WARN_ON (!list_empty (&knet->mux_list)); + +mutex_destroy (&knet->mutex); }static struct pernet_operations kcm_net_ops = {
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 140/285 octeontx2-af: Fix truncation of smq in CN10K NIX AQ enqueue mbox handler
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Geetha sowjanya <[email protected]>
[ Upstream commit 29fe7a1b62717d58f033009874554d99d71f7d37 ]
The smq value used in the CN10K NIX AQ instruction enqueue mailbox handler was truncated to 9-bit value from 10-bit value because of typecasting the CN10K mbox request structure to the CN9K structure. Though this hasn't caused any problems when programming the NIX SQ context to the HW because the context structure is the same size. However, this causes a problem when accessing the structure parameters. This patch reads the right smq value for each platform.
--- .../ethernet/marvell/octeontx2/af/rvu_nix.c | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-)
drivers/net/ethernet/marvell/octeontx2/af/rvu_nix.c +19 -2
@@ -846,6 +846,21 @@ static int nix_aq_enqueue_wait(struct rvu *rvu, struct rvu_block *block,return 0 ; } +static void nix_get_aq_req_smq (struct rvu *rvu,struct nix_aq_enq_req *req, +u16 *smq,u16 *smq_mask) +{ +struct nix_cn10k_aq_enq_req *aq_req; + +if (!is_rvu_otx2 (rvu)) { + aq_req = (struct nix_cn10k_aq_enq_req *)req; + *smq = aq_req->sq.smq; + *smq_mask = aq_req->sq_mask.smq; + }else { + *smq = req->sq.smq; + *smq_mask = req->sq_mask.smq; + } +} +static int rvu_nix_blk_aq_enq_inst (struct rvu *rvu,struct nix_hw *nix_hw,struct nix_aq_enq_req *req,struct nix_aq_enq_rsp *rsp)
@@ -857,6 +872,7 @@ static int rvu_nix_blk_aq_enq_inst(struct rvu *rvu, struct nix_hw *nix_hw,struct rvu_block *block;struct admin_queue *aq;struct rvu_pfvf *pfvf; +u16 smq, smq_mask;void *ctx, *mask;bool ena;u64 cfg;
@@ -928,13 +944,14 @@ static int rvu_nix_blk_aq_enq_inst(struct rvu *rvu, struct nix_hw *nix_hw,if (rc)return rc; +nix_get_aq_req_smq (rvu, req, &smq, &smq_mask);/* Check if SQ pointed SMQ belongs to this PF/VF or not */ if (req->ctype ==NIX_AQ_CTYPE_SQ && ((req->op ==NIX_AQ_INSTOP_INIT && req->sq.ena) || (req->op ==NIX_AQ_INSTOP_WRITE && - req->sq_mask.ena && req->sq_mask.smq && req->sq.ena))) { + req->sq_mask.ena && req->sq.ena && smq_mask))) {if (!is_valid_txschq (rvu, blkaddr,NIX_TXSCH_LVL_SMQ , - pcifunc, req->sq.smq)) + pcifunc, smq))return NIX_AF_ERR_AQ_ENQUEUE ; }
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 141/285 igc: Change IGC_MIN to allow set rx/tx value between 64 and 80
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Olga Zaborska <[email protected]>
[ Upstream commit 5aa48279712e1f134aac908acde4df798955a955 ]
Change the minimum value of RX/TX descriptors to 64 to enable setting the rx/tx value between 64 and 80. All igc devices can use as low as 64 descriptors. This change will unify igc with other drivers.
Based on commit 7b1be1987c1e ("e1000e: lower ring minimum size to 64")
--- drivers/net/ethernet/intel/igc/igc.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/ethernet/intel/igc/igc.h +2 -2
@@ -368,11 +368,11 @@ static inline u32 igc_rss_type(const union igc_adv_rx_desc *rx_desc)/* TX/RX descriptor defines */ #define IGC_DEFAULT_TXD 256#define IGC_DEFAULT_TX_WORK 128 -#define IGC_MIN_TXD 80 +#define IGC_MIN_TXD 64#define IGC_MAX_TXD 4096#define IGC_DEFAULT_RXD 256 -#define IGC_MIN_RXD 80 +#define IGC_MIN_RXD 64#define IGC_MAX_RXD 4096/* Supported Rx Buffer Sizes */
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 142/285 igbvf: Change IGBVF_MIN to allow set rx/tx value between 64 and 80
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Olga Zaborska <[email protected]>
[ Upstream commit 8360717524a24a421c36ef8eb512406dbd42160a ]
Change the minimum value of RX/TX descriptors to 64 to enable setting the rx/tx value between 64 and 80. All igbvf devices can use as low as 64 descriptors. This change will unify igbvf with other drivers.
Based on commit 7b1be1987c1e ("e1000e: lower ring minimum size to 64")
--- drivers/net/ethernet/intel/igbvf/igbvf.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/ethernet/intel/igbvf/igbvf.h +2 -2
@@ -39,11 +39,11 @@ enum latency_range {/* Tx/Rx descriptor defines */ #define IGBVF_DEFAULT_TXD 256#define IGBVF_MAX_TXD 4096 -#define IGBVF_MIN_TXD 80 +#define IGBVF_MIN_TXD 64#define IGBVF_DEFAULT_RXD 256#define IGBVF_MAX_RXD 4096 -#define IGBVF_MIN_RXD 80 +#define IGBVF_MIN_RXD 64#define IGBVF_MIN_ITR_USECS 10/* 100000 irq/sec */ #define IGBVF_MAX_ITR_USECS 10000/* 100 irq/sec */
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 143/285 igb: Change IGB_MIN to allow set rx/tx value between 64 and 80
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Olga Zaborska <[email protected]>
[ Upstream commit 6319685bdc8ad5310890add907b7c42f89302886 ]
Change the minimum value of RX/TX descriptors to 64 to enable setting the rx/tx value between 64 and 80. All igb devices can use as low as 64 descriptors. This change will unify igb with other drivers.
Based on commit 7b1be1987c1e ("e1000e: lower ring minimum size to 64")
--- drivers/net/ethernet/intel/igb/igb.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/ethernet/intel/igb/igb.h +2 -2
@@ -34,11 +34,11 @@ struct igb_adapter;/* TX/RX descriptor defines */ #define IGB_DEFAULT_TXD 256#define IGB_DEFAULT_TX_WORK 128 -#define IGB_MIN_TXD 80 +#define IGB_MIN_TXD 64#define IGB_MAX_TXD 4096#define IGB_DEFAULT_RXD 256 -#define IGB_MIN_RXD 80 +#define IGB_MIN_RXD 64#define IGB_MAX_RXD 4096#define IGB_DEFAULT_ITR 3/* dynamic */
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 144/285 s390/zcrypt: dont leak memory if dev_set_name() fails
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko <[email protected]>
[ Upstream commit 6252f47b78031979ad919f971dc8468b893488bd ]
When dev_set_name() fails, zcdn_create() doesn't free the newly allocated resources. Do it.
--- drivers/s390/crypto/zcrypt_api.c | 1 + 1 file changed, 1 insertion(+)
drivers/s390/crypto/zcrypt_api.c +1 -0
@@ -413,6 +413,7 @@ static int zcdn_create(const char *name) ZCRYPT_NAME "_%d", (int)MINOR(devt)); nodename[sizeof (nodename) -1 ] ='\0' ;if (dev_set_name (&zcdndev->device, nodename)) { +kfree (zcdndev); rc = -EINVAL ; goto unlockout; }
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 145/285 regulator: tps6594-regulator: Fix random kernel crash
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jerome Neanne <[email protected]>
[ Upstream commit ca0e36e3e39a4e8b5a4b647dff8c5938ca6ccbec ]
Random kernel crash detected in TI CICD when regulator driver is added. This is root caused to irq index increment being done twice causing irq_data being allocated outside of the range.
- Rework tps6594_request_reg_irqs with correct index increment
- Adjust irq_data kmalloc size to the exact size needed for the device
This has been reported on TI mainline. No public bug report associated.
--- drivers/regulator/tps6594-regulator.c | 31 +++++++++++++-------------- 1 file changed, 15 insertions(+), 16 deletions(-)
drivers/regulator/tps6594-regulator.c +15 -16
@@ -384,21 +384,19 @@ static int tps6594_request_reg_irqs(struct platform_device *pdev,if (irq <0 )return -EINVAL ; - irq_data[*irq_idx + j].dev = tps->dev; - irq_data[*irq_idx + j].type = irq_type; - irq_data[*irq_idx + j].rdev = rdev; + irq_data[*irq_idx].dev = tps->dev; + irq_data[*irq_idx].type = irq_type; + irq_data[*irq_idx].rdev = rdev; error =devm_request_threaded_irq (tps->dev, irq,NULL , - tps6594_regulator_irq_handler, -IRQF_ONESHOT , - irq_type->irq_name, - &irq_data[*irq_idx]); - (*irq_idx)++; + tps6594_regulator_irq_handler,IRQF_ONESHOT , + irq_type->irq_name, &irq_data[*irq_idx]);if (error) {dev_err (tps->dev,"tps6594 failed to request %s IRQ %d: %d\n" , irq_type->irq_name, irq, error);return error; } + (*irq_idx)++; }return 0 ; }
@@ -420,8 +418,8 @@ static int tps6594_regulator_probe(struct platform_device *pdev)int error, i, irq, multi, delta;int irq_idx =0 ;int buck_idx =0 ; -int ext_reg_irq_nb =2 ; - +size_t ext_reg_irq_nb =2 ; +size_t reg_irq_nb;enum {MULTI_BUCK12 ,MULTI_BUCK123 ,
@@ -484,15 +482,16 @@ static int tps6594_regulator_probe(struct platform_device *pdev) } } -if (tps->chip_id ==LP8764 ) +if (tps->chip_id ==LP8764 ) {/* There is only 4 buck on LP8764 */ buck_configured[4 ] =1 ; + reg_irq_nb =size_mul (REGS_INT_NB , (BUCK_NB -1 )); + }else { + reg_irq_nb =size_mul (REGS_INT_NB , (size_add (BUCK_NB ,LDO_NB ))); + } - irq_data =devm_kmalloc_array (tps->dev, -REGS_INT_NB *sizeof (struct tps6594_regulator_irq_data ), -ARRAY_SIZE (tps6594_bucks_irq_types) + -ARRAY_SIZE (tps6594_ldos_irq_types), -GFP_KERNEL ); + irq_data =devm_kmalloc_array (tps->dev, reg_irq_nb, +sizeof (struct tps6594_regulator_irq_data ),GFP_KERNEL );if (!irq_data)return -ENOMEM ;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 146/285 idr: fix param name in idr_alloc_cyclic() doc
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ariel Marcovitch <[email protected]>
[ Upstream commit 2a15de80dd0f7e04a823291aa9eb49c5294f56af ]
The relevant parameter is 'start' and not 'nextid'
--- lib/idr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
lib/idr.c +1 -1
@@ -100,7 +100,7 @@ EXPORT_SYMBOL_GPL(idr_alloc);* @end: The maximum ID (exclusive). * @gfp: Memory allocation flags. * -* Allocates an unused ID in the range specified by @nextid and @end. If +* Allocates an unused ID in the range specified by @start and @end. If * @end is <= 0, it is treated as one larger than %INT_MAX. This allows * callers to use @start + N as @end as long as N is within integer range. * The search for an unused ID will start at the last ID allocated and will
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 147/285 ip_tunnels: use DEV_STATS_INC()
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 9b271ebaf9a2c5c566a54bc6cd915962e8241130 ]
syzbot/KCSAN reported data-races in iptunnel_xmit_stats() [1]
This can run from multiple cpus without mutual exclusion.
Adopt SMP safe DEV_STATS_INC() to update dev->stats fields.
[1]
BUG: KCSAN: data-race in iptunnel_xmit / iptunnel_xmit
read-write to 0xffff8881353df170 of 8 bytes by task 30263 on cpu 1:
iptunnel_xmit_stats include/net/ip_tunnels.h:493 [inline] iptunnel_xmit+0x432/0x4a0 net/ipv4/ip_tunnel_core.c:87 ip_tunnel_xmit+0x1477/0x1750 net/ipv4/ip_tunnel.c:831 __gre_xmit net/ipv4/ip_gre.c:469 [inline] ipgre_xmit+0x516/0x570 net/ipv4/ip_gre.c:662 __netdev_start_xmit include/linux/netdevice.h:4889 [inline] netdev_start_xmit include/linux/netdevice.h:4903 [inline] xmit_one net/core/dev.c:3544 [inline] dev_hard_start_xmit+0x11b/0x3f0 net/core/dev.c:3560 __dev_queue_xmit+0xeee/0x1de0 net/core/dev.c:4340 dev_queue_xmit include/linux/netdevice.h:3082 [inline] __bpf_tx_skb net/core/filter.c:2129 [inline] __bpf_redirect_no_mac net/core/filter.c:2159 [inline] __bpf_redirect+0x723/0x9c0 net/core/filter.c:2182 ____bpf_clone_redirect net/core/filter.c:2453 [inline] bpf_clone_redirect+0x16c/0x1d0 net/core/filter.c:2425 ___bpf_prog_run+0xd7d/0x41e0 kernel/bpf/core.c:1954 __bpf_prog_run512+0x74/0xa0 kernel/bpf/core.c:2195 bpf_dispatcher_nop_func include/linux/bpf.h:1181 [inline] __bpf_prog_run include/linux/filter.h:609 [inline] bpf_prog_run include/linux/filter.h:616 [inline] bpf_test_run+0x15d/0x3d0 net/bpf/test_run.c:423 bpf_prog_test_run_skb+0x77b/0xa00 net/bpf/test_run.c:1045 bpf_prog_test_run+0x265/0x3d0 kernel/bpf/syscall.c:3996 __sys_bpf+0x3af/0x780 kernel/bpf/syscall.c:5353 __do_sys_bpf kernel/bpf/syscall.c:5439 [inline] __se_sys_bpf kernel/bpf/syscall.c:5437 [inline] __x64_sys_bpf+0x43/0x50 kernel/bpf/syscall.c:5437 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd
read-write to 0xffff8881353df170 of 8 bytes by task 30249 on cpu 0:
iptunnel_xmit_stats include/net/ip_tunnels.h:493 [inline] iptunnel_xmit+0x432/0x4a0 net/ipv4/ip_tunnel_core.c:87 ip_tunnel_xmit+0x1477/0x1750 net/ipv4/ip_tunnel.c:831 __gre_xmit net/ipv4/ip_gre.c:469 [inline] ipgre_xmit+0x516/0x570 net/ipv4/ip_gre.c:662 __netdev_start_xmit include/linux/netdevice.h:4889 [inline] netdev_start_xmit include/linux/netdevice.h:4903 [inline] xmit_one net/core/dev.c:3544 [inline] dev_hard_start_xmit+0x11b/0x3f0 net/core/dev.c:3560 __dev_queue_xmit+0xeee/0x1de0 net/core/dev.c:4340 dev_queue_xmit include/linux/netdevice.h:3082 [inline] __bpf_tx_skb net/core/filter.c:2129 [inline] __bpf_redirect_no_mac net/core/filter.c:2159 [inline] __bpf_redirect+0x723/0x9c0 net/core/filter.c:2182 ____bpf_clone_redirect net/core/filter.c:2453 [inline] bpf_clone_redirect+0x16c/0x1d0 net/core/filter.c:2425 ___bpf_prog_run+0xd7d/0x41e0 kernel/bpf/core.c:1954 __bpf_prog_run512+0x74/0xa0 kernel/bpf/core.c:2195 bpf_dispatcher_nop_func include/linux/bpf.h:1181 [inline] __bpf_prog_run include/linux/filter.h:609 [inline] bpf_prog_run include/linux/filter.h:616 [inline] bpf_test_run+0x15d/0x3d0 net/bpf/test_run.c:423 bpf_prog_test_run_skb+0x77b/0xa00 net/bpf/test_run.c:1045 bpf_prog_test_run+0x265/0x3d0 kernel/bpf/syscall.c:3996 __sys_bpf+0x3af/0x780 kernel/bpf/syscall.c:5353 __do_sys_bpf kernel/bpf/syscall.c:5439 [inline] __se_sys_bpf kernel/bpf/syscall.c:5437 [inline] __x64_sys_bpf+0x43/0x50 kernel/bpf/syscall.c:5437 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd
value changed: 0x0000000000018830 -> 0x0000000000018831
Reported by Kernel Concurrency Sanitizer on:
CPU: 0 PID: 30249 Comm: syz-executor.4 Not tainted 6.5.0-syzkaller-11704-g3f86ed6ec0b3 #0
--- include/net/ip_tunnels.h | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-)
include/net/ip_tunnels.h +7 -8
@@ -482,15 +482,14 @@ static inline void iptunnel_xmit_stats(struct net_device *dev, int pkt_len)u64_stats_inc (&tstats->tx_packets);u64_stats_update_end (&tstats->syncp);put_cpu_ptr (tstats); +return ; + } + +if (pkt_len <0 ) { +DEV_STATS_INC (dev, tx_errors); +DEV_STATS_INC (dev, tx_aborted_errors); }else { -struct net_device_stats *err_stats = &dev->stats; - -if (pkt_len <0 ) { - err_stats->tx_errors++; - err_stats->tx_aborted_errors++; - }else { - err_stats->tx_dropped++; - } +DEV_STATS_INC (dev, tx_dropped); } }
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 148/285 net/mlx5e: Clear mirred devices array if the rule is split
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jianbo Liu <[email protected]>
[ Upstream commit b7558a77529fef60e7992f40fb5353fed8be0cf8 ]
In the cited commit, the mirred devices are recorded and checked while parsing the actions. In order to avoid system crash, the duplicate action in a single rule is not allowed.
But the rule is actually break down into several FTEs in different tables, for either mirroring, or the specified types of actions which use post action infrastructure.
It will reject certain action list by mistake, for example:
actions:enp8s0f0_1,set(ipv4(ttl=63)),enp8s0f0_0,enp8s0f0_1.
Here the rule is split to two FTEs because of pedit action.
To fix this issue, when parsing the rule actions, reset if_count to clear the mirred devices array if the rule is split to multiple FTEs, and then the duplicate checking is restarted.
--- drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/ct.c | 4 +++- drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/mirred.c | 1 + drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/pedit.c | 4 +++- .../ethernet/mellanox/mlx5/core/en/tc/act/redirect_ingress.c | 1 + drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/vlan.c | 1 + .../net/ethernet/mellanox/mlx5/core/en/tc/act/vlan_mangle.c | 4 +++- drivers/net/ethernet/mellanox/mlx5/core/en_tc.c | 1 + 7 files changed, 13 insertions(+), 3 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/ct.c +3 -1
@@ -17,8 +17,10 @@ tc_act_parse_ct(struct mlx5e_tc_act_parse_state *parse_state,if (err)return err; -if (mlx5e_is_eswitch_flow (parse_state->flow)) +if (mlx5e_is_eswitch_flow (parse_state->flow)) { attr->esw_attr->split_count = attr->esw_attr->out_count; + parse_state->if_count =0 ; + } attr->flags |=MLX5_ATTR_FLAG_CT ;
drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/mirred.c +1 -0
@@ -294,6 +294,7 @@ parse_mirred_ovs_master(struct mlx5e_tc_act_parse_state *parse_state,if (err)return err; + parse_state->if_count =0 ; esw_attr->out_count++;return 0 ; }
drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/pedit.c +3 -1
@@ -98,8 +98,10 @@ tc_act_parse_pedit(struct mlx5e_tc_act_parse_state *parse_state, attr->action |=MLX5_FLOW_CONTEXT_ACTION_MOD_HDR ; -if (ns_type ==MLX5_FLOW_NAMESPACE_FDB ) +if (ns_type ==MLX5_FLOW_NAMESPACE_FDB ) { esw_attr->split_count = esw_attr->out_count; + parse_state->if_count =0 ; + }return 0 ; }
drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/redirect_ingress.c +1 -0
@@ -66,6 +66,7 @@ tc_act_parse_redirect_ingress(struct mlx5e_tc_act_parse_state *parse_state,if (err)return err; + parse_state->if_count =0 ; esw_attr->out_count++;return 0 ;
drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/vlan.c +1 -0
@@ -166,6 +166,7 @@ tc_act_parse_vlan(struct mlx5e_tc_act_parse_state *parse_state,return err; esw_attr->split_count = esw_attr->out_count; + parse_state->if_count =0 ;return 0 ; }
drivers/net/ethernet/mellanox/mlx5/core/en/tc/act/vlan_mangle.c +3 -1
@@ -65,8 +65,10 @@ tc_act_parse_vlan_mangle(struct mlx5e_tc_act_parse_state *parse_state,if (err)return err; -if (ns_type ==MLX5_FLOW_NAMESPACE_FDB ) +if (ns_type ==MLX5_FLOW_NAMESPACE_FDB ) { attr->esw_attr->split_count = attr->esw_attr->out_count; + parse_state->if_count =0 ; + }return 0 ; }
drivers/net/ethernet/mellanox/mlx5/core/en_tc.c +1 -0
@@ -3939,6 +3939,7 @@ parse_tc_actions(struct mlx5e_tc_act_parse_state *parse_state, } i_split = i +1 ; + parse_state->if_count =0 ;list_add (&attr->list, &flow->attrs); }
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 149/285 net/mlx5: Give esw_offloads_load/unload_rep() "mlx5_" prefix
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiri Pirko <[email protected]>
[ Upstream commit 9eca8bb8da4385b02bd02b6876af8d4225bf4713 ]
As esw_offloads_load/unload_rep() are used outside eswitch.c it is nicer for them to have "mlx5_" prefix. Add it.
Stable-dep-of: 344134609a56 ("mlx5/core: E-Switch, Create ACL FT for eswitch manager in switchdev mode")
--- drivers/net/ethernet/mellanox/mlx5/core/eswitch.c | 4 ++-- drivers/net/ethernet/mellanox/mlx5/core/eswitch.h | 4 ++-- .../net/ethernet/mellanox/mlx5/core/eswitch_offloads.c | 10 +++++----- 3 files changed, 9 insertions(+), 9 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +2 -2
@@ -1078,7 +1078,7 @@ int mlx5_eswitch_load_vport(struct mlx5_eswitch *esw, u16 vport_num,if (err)return err; - err =esw_offloads_load_rep (esw, vport_num); + err =mlx5_esw_offloads_load_rep (esw, vport_num);if (err) goto err_rep;
@@ -1091,7 +1091,7 @@ int mlx5_eswitch_load_vport(struct mlx5_eswitch *esw, u16 vport_num,void mlx5_eswitch_unload_vport (struct mlx5_eswitch *esw,u16 vport_num) { -esw_offloads_unload_rep (esw, vport_num); +mlx5_esw_offloads_unload_rep (esw, vport_num);mlx5_esw_vport_disable (esw, vport_num); }
drivers/net/ethernet/mellanox/mlx5/core/eswitch.h +2 -2
@@ -725,8 +725,8 @@ void mlx5_esw_set_spec_source_port(struct mlx5_eswitch *esw,u16 vport, struct mlx5_flow_spec *spec); -int esw_offloads_load_rep (struct mlx5_eswitch *esw,u16 vport_num); -void esw_offloads_unload_rep (struct mlx5_eswitch *esw,u16 vport_num); +int mlx5_esw_offloads_load_rep (struct mlx5_eswitch *esw,u16 vport_num); +void mlx5_esw_offloads_unload_rep (struct mlx5_eswitch *esw,u16 vport_num);int mlx5_esw_offloads_rep_load (struct mlx5_eswitch *esw,u16 vport_num);void mlx5_esw_offloads_rep_unload (struct mlx5_eswitch *esw,u16 vport_num);
drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +5 -5
@@ -2424,7 +2424,7 @@ void mlx5_esw_offloads_rep_unload(struct mlx5_eswitch *esw, u16 vport_num)__esw_offloads_unload_rep (esw, rep, rep_type); } -int esw_offloads_load_rep (struct mlx5_eswitch *esw,u16 vport_num) +int mlx5_esw_offloads_load_rep (struct mlx5_eswitch *esw,u16 vport_num) {int err;
@@ -2448,7 +2448,7 @@ int esw_offloads_load_rep(struct mlx5_eswitch *esw, u16 vport_num)return err; } -void esw_offloads_unload_rep (struct mlx5_eswitch *esw,u16 vport_num) +void mlx5_esw_offloads_unload_rep (struct mlx5_eswitch *esw,u16 vport_num) {if (esw->mode !=MLX5_ESWITCH_OFFLOADS )return ;
@@ -3355,7 +3355,7 @@ int esw_offloads_enable(struct mlx5_eswitch *esw) vport->info.link_state =MLX5_VPORT_ADMIN_STATE_DOWN ;/* Uplink vport rep must load first. */ - err =esw_offloads_load_rep (esw,MLX5_VPORT_UPLINK ); + err =mlx5_esw_offloads_load_rep (esw,MLX5_VPORT_UPLINK );if (err) goto err_uplink;
@@ -3366,7 +3366,7 @@ int esw_offloads_enable(struct mlx5_eswitch *esw)return 0 ; err_vports: -esw_offloads_unload_rep (esw,MLX5_VPORT_UPLINK ); +mlx5_esw_offloads_unload_rep (esw,MLX5_VPORT_UPLINK ); err_uplink:esw_offloads_steering_cleanup (esw); err_steering_init:
@@ -3404,7 +3404,7 @@ static int esw_offloads_stop(struct mlx5_eswitch *esw,void esw_offloads_disable (struct mlx5_eswitch *esw) {mlx5_eswitch_disable_pf_vf_vports (esw); -esw_offloads_unload_rep (esw,MLX5_VPORT_UPLINK ); +mlx5_esw_offloads_unload_rep (esw,MLX5_VPORT_UPLINK );esw_set_passing_vport_metadata (esw, false);esw_offloads_steering_cleanup (esw);mapping_destroy (esw->offloads.reg_c0_obj_pool);
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 150/285 net/mlx5: Rework devlink port alloc/free into init/cleanup
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiri Pirko <[email protected]>
[ Upstream commit 4c0dac1ef8abc6295a91197884f5ceb5d11c2bd9 ]
In order to prepare the devlink port registration function to be common for PFs/VFs and SFs, change the existing devlink port allocation and free functions into PF/VF init and cleanup, so similar helpers could be later on introduced for SFs. Make the init/cleanup helpers responsible for setting/clearing the vport->dl_port pointer.
Stable-dep-of: 344134609a56 ("mlx5/core: E-Switch, Create ACL FT for eswitch manager in switchdev mode")
--- .../mellanox/mlx5/core/esw/devlink_port.c | 65 ++++++++++++------- 1 file changed, 43 insertions(+), 22 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/esw/devlink_port.c +43 -22
@@ -22,20 +22,17 @@ static bool mlx5_esw_devlink_port_supported(struct mlx5_eswitch *esw, u16 vport_mlx5_core_is_ec_vf_vport (esw->dev, vport_num); } -static struct devlink_port *mlx5_esw_dl_port_alloc (struct mlx5_eswitch *esw,u16 vport_num) +static void mlx5_esw_offloads_pf_vf_devlink_port_attrs_set (struct mlx5_eswitch *esw, +u16 vport_num, +struct devlink_port *dl_port) {struct mlx5_core_dev *dev = esw->dev;struct devlink_port_attrs attrs = {};struct netdev_phys_item_id ppid = {}; -struct devlink_port *dl_port;u32 controller_num =0 ;bool external;u16 pfnum; - dl_port =kzalloc (sizeof (*dl_port),GFP_KERNEL ); -if (!dl_port) -return NULL ; -mlx5_esw_get_port_parent_id (dev, &ppid); pfnum =mlx5_get_dev_index (dev); external =mlx5_core_is_ecpf_esw_manager (dev);
@@ -63,12 +60,40 @@ static struct devlink_port *mlx5_esw_dl_port_alloc(struct mlx5_eswitch *esw, u16devlink_port_attrs_pci_vf_set (dl_port,0 , pfnum, vport_num -1 , false); } -return dl_port; } -static void mlx5_esw_dl_port_free (struct devlink_port *dl_port) +static int mlx5_esw_offloads_pf_vf_devlink_port_init (struct mlx5_eswitch *esw,u16 vport_num) +{ +struct devlink_port *dl_port; +struct mlx5_vport *vport; + +if (!mlx5_esw_devlink_port_supported (esw, vport_num)) +return 0 ; + + vport =mlx5_eswitch_get_vport (esw, vport_num); +if (IS_ERR (vport)) +return PTR_ERR (vport); + + dl_port =kzalloc (sizeof (*dl_port),GFP_KERNEL ); +if (!dl_port) +return -ENOMEM ; + +mlx5_esw_offloads_pf_vf_devlink_port_attrs_set (esw, vport_num, dl_port); + + vport->dl_port = dl_port; +return 0 ; +} + +static void mlx5_esw_offloads_pf_vf_devlink_port_cleanup (struct mlx5_eswitch *esw,u16 vport_num) { -kfree (dl_port); +struct mlx5_vport *vport; + + vport =mlx5_eswitch_get_vport (esw, vport_num); +if (IS_ERR (vport) || !vport->dl_port) +return ; + +kfree (vport->dl_port); + vport->dl_port =NULL ; }static const struct devlink_port_ops mlx5_esw_dl_port_ops = {
@@ -89,16 +114,17 @@ int mlx5_esw_offloads_devlink_port_register(struct mlx5_eswitch *esw, u16 vport_struct devlink *devlink;int err; -if (!mlx5_esw_devlink_port_supported (esw, vport_num)) -return 0 ; - vport =mlx5_eswitch_get_vport (esw, vport_num);if (IS_ERR (vport))return PTR_ERR (vport); - dl_port =mlx5_esw_dl_port_alloc (esw, vport_num); + err =mlx5_esw_offloads_pf_vf_devlink_port_init (esw, vport_num); +if (err) +return err; + + dl_port = vport->dl_port;if (!dl_port) -return -ENOMEM ; +return 0 ; devlink =priv_to_devlink (dev); dl_port_index =mlx5_esw_vport_to_devlink_port_index (dev, vport_num);
@@ -111,13 +137,12 @@ int mlx5_esw_offloads_devlink_port_register(struct mlx5_eswitch *esw, u16 vport_if (err) goto rate_err; - vport->dl_port = dl_port;return 0 ; rate_err:devl_port_unregister (dl_port); reg_err: -mlx5_esw_dl_port_free (dl_port); +mlx5_esw_offloads_pf_vf_devlink_port_cleanup (esw, vport_num);return err; }
@@ -125,11 +150,8 @@ void mlx5_esw_offloads_devlink_port_unregister(struct mlx5_eswitch *esw, u16 vpo {struct mlx5_vport *vport; -if (!mlx5_esw_devlink_port_supported (esw, vport_num)) -return ; - vport =mlx5_eswitch_get_vport (esw, vport_num); -if (IS_ERR (vport)) +if (IS_ERR (vport) || !vport->dl_port)return ;if (vport->dl_port->devlink_rate) {
@@ -138,8 +160,7 @@ void mlx5_esw_offloads_devlink_port_unregister(struct mlx5_eswitch *esw, u16 vpo }devl_port_unregister (vport->dl_port); -mlx5_esw_dl_port_free (vport->dl_port); - vport->dl_port =NULL ; +mlx5_esw_offloads_pf_vf_devlink_port_cleanup (esw, vport_num); }struct devlink_port *mlx5_esw_offloads_devlink_port (struct mlx5_eswitch *esw,u16 vport_num)
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 151/285 net/mlx5: Push devlink port PF/VF init/cleanup calls out of devlink_port_register/unregister()
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiri Pirko <[email protected]>
[ Upstream commit d9833bcfe840fff5d368b1c7c68e05c95be8d19c ]
In order to prepare for mlx5_esw_offloads_devlink_port_register/unregister() to be used for SFs as well, push out the PF/VF specific init/cleanup calls outside. Introduce mlx5_eswitch_load/unload_pf_vf_vport() and call them from there. Use these new helpers of PF/VF loading and make mlx5_eswitch_local/unload_vport() reusable for SFs.
Stable-dep-of: 344134609a56 ("mlx5/core: E-Switch, Create ACL FT for eswitch manager in switchdev mode")
--- .../mellanox/mlx5/core/esw/devlink_port.c | 13 ++---- .../net/ethernet/mellanox/mlx5/core/eswitch.c | 45 ++++++++++++++----- .../net/ethernet/mellanox/mlx5/core/eswitch.h | 4 ++ .../mellanox/mlx5/core/eswitch_offloads.c | 16 +++++++ 4 files changed, 58 insertions(+), 20 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/esw/devlink_port.c +3 -10
@@ -62,7 +62,7 @@ static void mlx5_esw_offloads_pf_vf_devlink_port_attrs_set(struct mlx5_eswitch * } } -static int mlx5_esw_offloads_pf_vf_devlink_port_init (struct mlx5_eswitch *esw,u16 vport_num) +int mlx5_esw_offloads_pf_vf_devlink_port_init (struct mlx5_eswitch *esw,u16 vport_num) {struct devlink_port *dl_port;struct mlx5_vport *vport;
@@ -84,7 +84,7 @@ static int mlx5_esw_offloads_pf_vf_devlink_port_init(struct mlx5_eswitch *esw, ureturn 0 ; } -static void mlx5_esw_offloads_pf_vf_devlink_port_cleanup (struct mlx5_eswitch *esw,u16 vport_num) +void mlx5_esw_offloads_pf_vf_devlink_port_cleanup (struct mlx5_eswitch *esw,u16 vport_num) {struct mlx5_vport *vport;
@@ -118,10 +118,6 @@ int mlx5_esw_offloads_devlink_port_register(struct mlx5_eswitch *esw, u16 vport_if (IS_ERR (vport))return PTR_ERR (vport); - err =mlx5_esw_offloads_pf_vf_devlink_port_init (esw, vport_num); -if (err) -return err; - dl_port = vport->dl_port;if (!dl_port)return 0 ;
@@ -131,7 +127,7 @@ int mlx5_esw_offloads_devlink_port_register(struct mlx5_eswitch *esw, u16 vport_ err =devl_port_register_with_ops (devlink, dl_port, dl_port_index, &mlx5_esw_dl_port_ops);if (err) - goto reg_err; +return err; err =devl_rate_leaf_create (dl_port, vport,NULL );if (err)
@@ -141,8 +137,6 @@ int mlx5_esw_offloads_devlink_port_register(struct mlx5_eswitch *esw, u16 vport_ rate_err:devl_port_unregister (dl_port); -reg_err: -mlx5_esw_offloads_pf_vf_devlink_port_cleanup (esw, vport_num);return err; }
@@ -160,7 +154,6 @@ void mlx5_esw_offloads_devlink_port_unregister(struct mlx5_eswitch *esw, u16 vpo }devl_port_unregister (vport->dl_port); -mlx5_esw_offloads_pf_vf_devlink_port_cleanup (esw, vport_num); }struct devlink_port *mlx5_esw_offloads_devlink_port (struct mlx5_eswitch *esw,u16 vport_num)
drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +35 -10
105 lines not on this page · raw message
drivers/net/ethernet/mellanox/mlx5/core/eswitch.h +4 -0
@@ -725,6 +725,8 @@ void mlx5_esw_set_spec_source_port(struct mlx5_eswitch *esw,u16 vport, struct mlx5_flow_spec *spec); +int mlx5_esw_offloads_init_pf_vf_rep (struct mlx5_eswitch *esw,u16 vport_num); +void mlx5_esw_offloads_cleanup_pf_vf_rep (struct mlx5_eswitch *esw,u16 vport_num);int mlx5_esw_offloads_load_rep (struct mlx5_eswitch *esw,u16 vport_num);void mlx5_esw_offloads_unload_rep (struct mlx5_eswitch *esw,u16 vport_num);
@@ -739,6 +741,8 @@ int mlx5_eswitch_load_vf_vports(struct mlx5_eswitch *esw, u16 num_vfs, enum mlx5_eswitch_vport_event enabled_events);void mlx5_eswitch_unload_vf_vports (struct mlx5_eswitch *esw,u16 num_vfs); +int mlx5_esw_offloads_pf_vf_devlink_port_init (struct mlx5_eswitch *esw,u16 vport_num); +void mlx5_esw_offloads_pf_vf_devlink_port_cleanup (struct mlx5_eswitch *esw,u16 vport_num);int mlx5_esw_offloads_devlink_port_register (struct mlx5_eswitch *esw,u16 vport_num);void mlx5_esw_offloads_devlink_port_unregister (struct mlx5_eswitch *esw,u16 vport_num);struct devlink_port *mlx5_esw_offloads_devlink_port (struct mlx5_eswitch *esw,u16 vport_num);
drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +16 -0
@@ -2424,6 +2424,22 @@ void mlx5_esw_offloads_rep_unload(struct mlx5_eswitch *esw, u16 vport_num)__esw_offloads_unload_rep (esw, rep, rep_type); } +int mlx5_esw_offloads_init_pf_vf_rep (struct mlx5_eswitch *esw,u16 vport_num) +{ +if (esw->mode !=MLX5_ESWITCH_OFFLOADS ) +return 0 ; + +return mlx5_esw_offloads_pf_vf_devlink_port_init (esw, vport_num); +} + +void mlx5_esw_offloads_cleanup_pf_vf_rep (struct mlx5_eswitch *esw,u16 vport_num) +{ +if (esw->mode !=MLX5_ESWITCH_OFFLOADS ) +return ; + +mlx5_esw_offloads_pf_vf_devlink_port_cleanup (esw, vport_num); +} +int mlx5_esw_offloads_load_rep (struct mlx5_eswitch *esw,u16 vport_num) {int err;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 152/285 mlx5/core: E-Switch, Create ACL FT for eswitch manager in switchdev mode
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bodong Wang <[email protected]>
[ Upstream commit 344134609a564f28b3cc81ca6650319ccd5d8961 ]
ACL flow table is required in switchdev mode when metadata is enabled, driver creates such table when loading each vport. However, not every vport is loaded in switchdev mode. Such as ECPF if it's the eswitch manager. In this case, ACL flow table is still needed.
To make it modularized, create ACL flow table for eswitch manager as default and skip such operations when loading manager vport.
Also, there is no need to load the eswitch manager vport in switchdev mode. This means there is no need to load it on regular connect-x HCAs where the PF is the eswitch manager. This will avoid creating duplicate ACL flow table for host PF vport.
--- .../net/ethernet/mellanox/mlx5/core/eswitch.c | 21 ++++++-- .../mellanox/mlx5/core/eswitch_offloads.c | 49 +++++++++++++------ 2 files changed, 51 insertions(+), 19 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/eswitch.c +16 -5
@@ -1212,12 +1212,19 @@ int mlx5_eswitch_enable_pf_vf_vports(struct mlx5_eswitch *esw, enum mlx5_eswitch_vport_event enabled_events) { + bool pf_needed;int ret; + pf_needed =mlx5_core_is_ecpf_esw_manager (esw->dev) || + esw->mode ==MLX5_ESWITCH_LEGACY ; +/* Enable PF vport */ - ret =mlx5_eswitch_load_pf_vf_vport (esw,MLX5_VPORT_PF , enabled_events); -if (ret) -return ret; +if (pf_needed) { + ret =mlx5_eswitch_load_pf_vf_vport (esw,MLX5_VPORT_PF , + enabled_events); +if (ret) +return ret; + }/* Enable external host PF HCA */ ret =host_pf_enable_hca (esw->dev);
@@ -1253,7 +1260,8 @@ mlx5_eswitch_enable_pf_vf_vports(struct mlx5_eswitch *esw, ecpf_err:host_pf_disable_hca (esw->dev); pf_hca_err: -mlx5_eswitch_unload_pf_vf_vport (esw,MLX5_VPORT_PF ); +if (pf_needed) +mlx5_eswitch_unload_pf_vf_vport (esw,MLX5_VPORT_PF );return ret; }
@@ -1271,7 +1279,10 @@ void mlx5_eswitch_disable_pf_vf_vports(struct mlx5_eswitch *esw) }host_pf_disable_hca (esw->dev); -mlx5_eswitch_unload_pf_vf_vport (esw,MLX5_VPORT_PF ); + +if (mlx5_core_is_ecpf_esw_manager (esw->dev) || + esw->mode ==MLX5_ESWITCH_LEGACY ) +mlx5_eswitch_unload_pf_vf_vport (esw,MLX5_VPORT_PF ); }static void mlx5_eswitch_get_devlink_param (struct mlx5_eswitch *esw)
drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads.c +35 -14
82 lines not on this page · raw message
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 153/285 net: dsa: sja1105: fix bandwidth discrepancy between tc-cbs software and offload
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vladimir Oltean <[email protected]>
[ Upstream commit 954ad9bf13c4f95a4958b5f8433301f2ab99e1f5 ]
More careful measurement of the tc-cbs bandwidth shows that the stream bandwidth (effectively idleslope) increases, there is a larger and larger discrepancy between the rate limit obtained by the software Qdisc, and the rate limit obtained by its offloaded counterpart.
The discrepancy becomes so large, that e.g. at an idleslope of 40000 (40Mbps), the offloaded cbs does not actually rate limit anything, and traffic will pass at line rate through a 100 Mbps port.
The reason for the discrepancy is that the hardware documentation I've been following is incorrect. UM11040.pdf (for SJA1105P/Q/R/S) states about IDLE_SLOPE that it is "the rate (in unit of bytes/sec) at which the credit counter is increased".
Cross-checking with UM10944.pdf (for SJA1105E/T) and UM11107.pdf (for SJA1110), the wording is different: "This field specifies the value, in bytes per second times link speed, by which the credit counter is increased".
So there's an extra scaling for link speed that the driver is currently not accounting for, and apparently (empirically), that link speed is expressed in Kbps.
I've pondered whether to pollute the sja1105_mac_link_up() implementation with CBS shaper reprogramming, but I don't think it is worth it. IMO, the UAPI exposed by tc-cbs requires user space to recalculate the sendslope anyway, since the formula for that depends on port_transmit_rate (see man tc-cbs), which is not an invariant from tc's perspective.
So we use the offload->sendslope and offload->idleslope to deduce the original port_transmit_rate from the CBS formula, and use that value to scale the offload->sendslope and offload->idleslope to values that the hardware understands.
Some numerical data points:
40Mbps stream, max interfering frame size 1500, port speed 100M
---------------------------------------------------------------
tc-cbs parameters:
idleslope 40000 sendslope -60000 locredit -900 hicredit 600
which result in hardware values:
Before (doesn't work) After (works) credit_hi 600 600 credit_lo 900 900 send_slope 7500000 75 idle_slope 5000000 50
40Mbps stream, max interfering frame size 1500, port speed 1G
-------------------------------------------------------------
tc-cbs parameters:
idleslope 40000 sendslope -960000 locredit -1440 hicredit 60
which result in hardware values:
Before (doesn't work) After (works) credit_hi 60 60 credit_lo 1440 1440 send_slope 120000000 120 idle_slope 5000000 5
5.12Mbps stream, max interfering frame size 1522, port speed 100M
-----------------------------------------------------------------
tc-cbs parameters:
idleslope 5120 sendslope -94880 locredit -1444 hicredit 77
which result in hardware values:
Before (doesn't work) After (works) credit_hi 77 77 credit_lo 1444 1444 send_slope 11860000 118 idle_slope 640000 6
Tested on SJA1105T, SJA1105S and SJA1110A, at 1Gbps and 100Mbps.
--- drivers/net/dsa/sja1105/sja1105_main.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-)
drivers/net/dsa/sja1105/sja1105_main.c +12 -3
@@ -2157,6 +2157,7 @@ static int sja1105_setup_tc_cbs(struct dsa_switch *ds, int port, {struct sja1105_private *priv = ds->priv;struct sja1105_cbs_entry *cbs; +s64 port_transmit_rate_kbps;int index;if (!offload->enable)
@@ -2174,9 +2175,17 @@ static int sja1105_setup_tc_cbs(struct dsa_switch *ds, int port,*/ cbs->credit_hi = offload->hicredit; cbs->credit_lo =abs (offload->locredit); -/* User space is in kbits/sec, hardware in bytes/sec */ - cbs->idle_slope = offload->idleslope *BYTES_PER_KBIT ; - cbs->send_slope =abs (offload->sendslope *BYTES_PER_KBIT ); +/* User space is in kbits/sec, while the hardware in bytes/sec times +* link speed. Since the given offload->sendslope is good only for the +* current link speed anyway, and user space is likely to reprogram it +* when that changes, don't even bother to track the port's link speed, +* but deduce the port transmit rate from idleslope - sendslope. +*/ + port_transmit_rate_kbps = offload->idleslope - offload->sendslope; + cbs->idle_slope =div_s64 (offload->idleslope *BYTES_PER_KBIT , + port_transmit_rate_kbps); + cbs->send_slope =div_s64 (abs (offload->sendslope *BYTES_PER_KBIT ), + port_transmit_rate_kbps);/* Convert the negative values from 64-bit 2's complement * to 32-bit 2's complement (for the case of 0x80000000 whose * negative is still negative).
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 154/285 net: dsa: sja1105: fix -ENOSPC when replacing the same tc-cbs too many times
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vladimir Oltean <[email protected]>
[ Upstream commit 894cafc5c62ccced758077bd4e970dc714c42637 ]
After running command [2] too many times in a row:
[1] $ tc qdisc add dev sw2p0 root handle 1: mqprio num_tc 8 \ map 0 1 2 3 4 5 6 7 queues 1@0 1@1 1@2 1@3 1@4 1@5 1@6 1@7 hw 0 [2] $ tc qdisc replace dev sw2p0 parent 1:1 cbs offload 1 \ idleslope 120000 sendslope -880000 locredit -1320 hicredit 180
(aka more than priv->info->num_cbs_shapers times)
we start seeing the following error message:
Error: Specified device failed to setup cbs hardware offload.
This comes from the fact that ndo_setup_tc(TC_SETUP_QDISC_CBS) presents the same API for the qdisc create and replace cases, and the sja1105 driver fails to distinguish between the 2. Thus, it always thinks that it must allocate the same shaper for a {port, queue} pair, when it may instead have to replace an existing one.
--- drivers/net/dsa/sja1105/sja1105_main.c | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-)
drivers/net/dsa/sja1105/sja1105_main.c +20 -3
@@ -2123,6 +2123,18 @@ static void sja1105_bridge_leave(struct dsa_switch *ds, int port,#define BYTES_PER_KBIT (1000LL / 8) +static int sja1105_find_cbs_shaper (struct sja1105_private *priv, +int port,int prio) +{ +int i; + +for (i =0 ; i < priv->info->num_cbs_shapers; i++) +if (priv->cbs[i].port == port && priv->cbs[i].prio == prio) +return i; + +return -1 ; +} +static int sja1105_find_unused_cbs_shaper (struct sja1105_private *priv) {int i;
@@ -2163,9 +2175,14 @@ static int sja1105_setup_tc_cbs(struct dsa_switch *ds, int port,if (!offload->enable)return sja1105_delete_cbs_shaper (priv, port, offload->queue); - index =sja1105_find_unused_cbs_shaper (priv); -if (index <0 ) -return -ENOSPC ; +/* The user may be replacing an existing shaper */ + index =sja1105_find_cbs_shaper (priv, port, offload->queue); +if (index <0 ) { +/* That isn't the case - see if we can allocate a new one */ + index =sja1105_find_unused_cbs_shaper (priv); +if (index <0 ) +return -ENOSPC ; + } cbs = &priv->cbs[index]; cbs->port = port;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 155/285 net: dsa: sja1105: complete tc-cbs offload support on SJA1110
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vladimir Oltean <[email protected]>
[ Upstream commit 180a7419fe4adc8d9c8e0ef0fd17bcdd0cf78acd ]
The blamed commit left this delta behind:
struct sja1105_cbs_entry {
- u64 port;
- u64 prio;
+ u64 port; /* Not used for SJA1110 */
+ u64 prio; /* Not used for SJA1110 */
u64 credit_hi;
u64 credit_lo;
u64 send_slope;
u64 idle_slope;
};
but did not actually implement tc-cbs offload fully for the new switch. The offload is accepted, but it doesn't work.
The difference compared to earlier switch generations is that now, the table of CBS shapers is sparse, because there are many more shapers, so the mapping between a {port, prio} and a table index is static, rather than requiring us to store the port and prio into the sja1105_cbs_entry.
So, the problem is that the code programs the CBS shaper parameters at a dynamic table index which is incorrect.
All that needs to be done for SJA1110 CBS shapers to work is to bypass the logic which allocates shapers in a dense manner, as for SJA1105, and use the fixed mapping instead.
--- drivers/net/dsa/sja1105/sja1105.h | 2 ++ drivers/net/dsa/sja1105/sja1105_main.c | 13 +++++++++++++ drivers/net/dsa/sja1105/sja1105_spi.c | 4 ++++ 3 files changed, 19 insertions(+)
drivers/net/dsa/sja1105/sja1105.h +2 -0
@@ -132,6 +132,8 @@ struct sja1105_info {int max_frame_mem;int num_ports;bool multiple_cascade_ports; +/* Every {port, TXQ} has its own CBS shaper */ +bool fixed_cbs_mapping;enum dsa_tag_protocol tag_proto;const struct sja1105_dynamic_table_ops *dyn_ops;const struct sja1105_table_ops *static_ops;
drivers/net/dsa/sja1105/sja1105_main.c +13 -0
@@ -2122,12 +2122,22 @@ static void sja1105_bridge_leave(struct dsa_switch *ds, int port, }#define BYTES_PER_KBIT (1000LL / 8) +/* Port 0 (the uC port) does not have CBS shapers */ +#define SJA1110_FIXED_CBS (port, prio) ((((port) - 1) * SJA1105_NUM_TC) + (prio))static int sja1105_find_cbs_shaper (struct sja1105_private *priv,int port,int prio) {int i; +if (priv->info->fixed_cbs_mapping) { + i =SJA1110_FIXED_CBS (port, prio); +if (i >=0 && i < priv->info->num_cbs_shapers) +return i; + +return -1 ; + } +for (i =0 ; i < priv->info->num_cbs_shapers; i++)if (priv->cbs[i].port == port && priv->cbs[i].prio == prio)return i;
@@ -2139,6 +2149,9 @@ static int sja1105_find_unused_cbs_shaper(struct sja1105_private *priv) {int i; +if (priv->info->fixed_cbs_mapping) +return -1 ; +for (i =0 ; i < priv->info->num_cbs_shapers; i++)if (!priv->cbs[i].idle_slope && !priv->cbs[i].send_slope)return i;
drivers/net/dsa/sja1105/sja1105_spi.c +4 -0
@@ -781,6 +781,7 @@ const struct sja1105_info sja1110a_info = { .tag_proto = DSA_TAG_PROTO_SJA1110, .can_limit_mcast_flood = true, .multiple_cascade_ports = true, + .fixed_cbs_mapping = true, .ptp_ts_bits = 32, .ptpegr_ts_bytes = 8, .max_frame_mem = SJA1110_MAX_FRAME_MEMORY,
@@ -831,6 +832,7 @@ const struct sja1105_info sja1110b_info = { .tag_proto = DSA_TAG_PROTO_SJA1110, .can_limit_mcast_flood = true, .multiple_cascade_ports = true, + .fixed_cbs_mapping = true, .ptp_ts_bits = 32, .ptpegr_ts_bytes = 8, .max_frame_mem = SJA1110_MAX_FRAME_MEMORY,
@@ -881,6 +883,7 @@ const struct sja1105_info sja1110c_info = { .tag_proto = DSA_TAG_PROTO_SJA1110, .can_limit_mcast_flood = true, .multiple_cascade_ports = true, + .fixed_cbs_mapping = true, .ptp_ts_bits = 32, .ptpegr_ts_bytes = 8, .max_frame_mem = SJA1110_MAX_FRAME_MEMORY,
@@ -931,6 +934,7 @@ const struct sja1105_info sja1110d_info = { .tag_proto = DSA_TAG_PROTO_SJA1110, .can_limit_mcast_flood = true, .multiple_cascade_ports = true, + .fixed_cbs_mapping = true, .ptp_ts_bits = 32, .ptpegr_ts_bytes = 8, .max_frame_mem = SJA1110_MAX_FRAME_MEMORY,
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 156/285 net: phylink: fix sphinx complaint about invalid literal
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jakub Kicinski <[email protected]>
[ Upstream commit 1a961e74d5abbea049588a3d74b759955b4ed9d5 ]
sphinx complains about the use of "%PHYLINK_PCS_NEG_*":
Documentation/networking/kapi:144: ./include/linux/phylink.h:601: WARNING: Inline literal start-string without end-string. Documentation/networking/kapi:144: ./include/linux/phylink.h:633: WARNING: Inline literal start-string without end-string.
These are not valid symbols so drop the '%' prefix.
Alternatively we could use %PHYLINK_PCS_NEG_\* (escape the *) or use normal literal ``PHYLINK_PCS_NEG_*`` but there is already a handful of un-adorned DEFINE_* in this file.
--- include/linux/phylink.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
include/linux/phylink.h +2 -2
@@ -615,7 +615,7 @@ void pcs_get_state(struct phylink_pcs *pcs,* * The %neg_mode argument should be tested via the phylink_mode_*() family of * functions, or for PCS that set pcs->neg_mode true, should be tested -* against the %PHYLINK_PCS_NEG_* definitions. +* against the PHYLINK_PCS_NEG_* definitions. */ int pcs_config(struct phylink_pcs *pcs, unsigned int neg_mode, phy_interface_t interface, const unsigned long *advertising,
@@ -645,7 +645,7 @@ void pcs_an_restart(struct phylink_pcs *pcs);* * The %mode argument should be tested via the phylink_mode_*() family of * functions, or for PCS that set pcs->neg_mode true, should be tested -* against the %PHYLINK_PCS_NEG_* definitions. +* against the PHYLINK_PCS_NEG_* definitions. */ void pcs_link_up (struct phylink_pcs *pcs,unsigned int neg_mode,phy_interface_t interface,int speed,int duplex);
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 157/285 bpf: Invoke __bpf_prog_exit_sleepable_recur() on recursion in kern_sys_bpf().
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastian Andrzej Siewior <[email protected]>
[ Upstream commit 7645629f7dc88cd777f98970134bf1a54c8d77e3 ]
If __bpf_prog_enter_sleepable_recur() detects recursion then it returns 0 without undoing rcu_read_lock_trace(), migrate_disable() or decrementing the recursion counter. This is fine in the JIT case because the JIT code will jump in the 0 case to the end and invoke the matching exit trampoline (__bpf_prog_exit_sleepable_recur()).
This is not the case in kern_sys_bpf() which returns directly to the caller with an error code.
Add __bpf_prog_exit_sleepable_recur() as clean up in the recursion case.
--- kernel/bpf/syscall.c | 1 + 1 file changed, 1 insertion(+)
kernel/bpf/syscall.c +1 -0
@@ -5307,6 +5307,7 @@ int kern_sys_bpf(int cmd, union bpf_attr *attr, unsigned int size) run_ctx.saved_run_ctx =NULL ;if (!__bpf_prog_enter_sleepable_recur (prog, &run_ctx)) {/* recursion detected */ +__bpf_prog_exit_sleepable_recur (prog,0 , &run_ctx);bpf_prog_put (prog);return -EBUSY ; }
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 158/285 bpf: Assign bpf_tramp_run_ctx::saved_run_ctx before recursion check.
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastian Andrzej Siewior <[email protected]>
[ Upstream commit 6764e767f4af1e35f87f3497e1182d945de37f93 ]
__bpf_prog_enter_recur() assigns bpf_tramp_run_ctx::saved_run_ctx before performing the recursion check which means in case of a recursion __bpf_prog_exit_recur() uses the previously set bpf_tramp_run_ctx::saved_run_ctx value.
__bpf_prog_enter_sleepable_recur() assigns bpf_tramp_run_ctx::saved_run_ctx after the recursion check which means in case of a recursion __bpf_prog_exit_sleepable_recur() uses an uninitialized value. This does not look right. If I read the entry trampoline code right, then bpf_tramp_run_ctx isn't initialized upfront.
Align __bpf_prog_enter_sleepable_recur() with __bpf_prog_enter_recur() and set bpf_tramp_run_ctx::saved_run_ctx before the recursion check is made. Remove the assignment of saved_run_ctx in kern_sys_bpf() since it happens a few cycles later.
--- kernel/bpf/syscall.c | 1 - kernel/bpf/trampoline.c | 5 ++--- 2 files changed, 2 insertions(+), 4 deletions(-)
kernel/bpf/syscall.c +0 -1
@@ -5304,7 +5304,6 @@ int kern_sys_bpf(int cmd, union bpf_attr *attr, unsigned int size) } run_ctx.bpf_cookie =0 ; - run_ctx.saved_run_ctx =NULL ;if (!__bpf_prog_enter_sleepable_recur (prog, &run_ctx)) {/* recursion detected */ __bpf_prog_exit_sleepable_recur (prog,0 , &run_ctx);
kernel/bpf/trampoline.c +2 -3
@@ -926,13 +926,12 @@ u64 notrace __bpf_prog_enter_sleepable_recur(struct bpf_prog *prog,migrate_disable ();might_fault (); + run_ctx->saved_run_ctx =bpf_set_run_ctx (&run_ctx->run_ctx); +if (unlikely (this_cpu_inc_return (*(prog->active)) !=1 )) {bpf_prog_inc_misses_counter (prog);return 0 ; } - - run_ctx->saved_run_ctx =bpf_set_run_ctx (&run_ctx->run_ctx); -return bpf_prog_start_time (); }
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 159/285 s390/bpf: Pass through tail call counter in trampolines
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilya Leoshkevich <[email protected]>
[ Upstream commit a192103a11465e9d517975c50f9944dc80e44d61 ]
s390x eBPF programs use the following extension to the s390x calling
convention: tail call counter is passed on stack at offset STK_OFF_TCCNT, which callees otherwise use as scratch space.
Currently trampoline does not respect this and clobbers tail call counter. This breaks enforcing tail call limits in eBPF programs, which have trampolines attached to them.
Fix by forwarding a copy of the tail call counter to the original eBPF program in the trampoline (for fexit), and by restoring it at the end of the trampoline (for fentry).
--- arch/s390/net/bpf_jit_comp.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
arch/s390/net/bpf_jit_comp.c +10 -0
@@ -2088,6 +2088,7 @@ struct bpf_tramp_jit {*/ int r14_off;/* Offset of saved %r14 */ int run_ctx_off;/* Offset of struct bpf_tramp_run_ctx */ +int tccnt_off;/* Offset of saved tailcall counter */ int do_fexit;/* do_fexit: label */ };
@@ -2258,12 +2259,16 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, tjit->r14_off =alloc_stack (tjit,sizeof (u64)); tjit->run_ctx_off =alloc_stack (tjit,sizeof (struct bpf_tramp_run_ctx )); + tjit->tccnt_off =alloc_stack (tjit,sizeof (u64));/* The caller has already reserved STACK_FRAME_OVERHEAD bytes. */ tjit->stack_size -=STACK_FRAME_OVERHEAD ; tjit->orig_stack_args_off = tjit->stack_size +STACK_FRAME_OVERHEAD ;/* aghi %r15,-stack_size */ EMIT4_IMM (0xa70b0000 ,REG_15 , -tjit->stack_size); +/* mvc tccnt_off(4,%r15),stack_size+STK_OFF_TCCNT(%r15) */ +_EMIT6 (0xd203f000 | tjit->tccnt_off, +0xf000 | (tjit->stack_size +STK_OFF_TCCNT ));/* stmg %r2,%rN,fwd_reg_args_off(%r15) */ if (nr_reg_args) EMIT6_DISP_LH(0xeb000000, 0x0024, REG_2,
@@ -2400,6 +2405,8 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im, (nr_stack_args *sizeof (u64) -1 ) <<16 | tjit->stack_args_off, 0xf000 | tjit->orig_stack_args_off); +/* mvc STK_OFF_TCCNT(4,%r15),tccnt_off(%r15) */ +_EMIT6 (0xd203f000 |STK_OFF_TCCNT ,0xf000 | tjit->tccnt_off);/* lgr %r1,%r8 */ EMIT4 (0xb9040000 ,REG_1 ,REG_8 );/* %r1() */
@@ -2456,6 +2463,9 @@ static int __arch_prepare_bpf_trampoline(struct bpf_tramp_image *im,if (flags & (BPF_TRAMP_F_CALL_ORIG |BPF_TRAMP_F_RET_FENTRY_RET ))EMIT6_DISP_LH (0xe3000000 ,0x0004 ,REG_2 ,REG_0 ,REG_15 , tjit->retval_off); +/* mvc stack_size+STK_OFF_TCCNT(4,%r15),tccnt_off(%r15) */ +_EMIT6 (0xd203f000 | (tjit->stack_size +STK_OFF_TCCNT ), +0xf000 | tjit->tccnt_off);/* aghi %r15,stack_size */ EMIT4_IMM (0xa70b0000 ,REG_15 , tjit->stack_size);/* Emit an expoline for the following indirect jump. */
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 160/285 bpf: bpf_sk_storage: Fix invalid wait context lockdep report
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Martin KaFai Lau <[email protected]>
[ Upstream commit a96a44aba556c42b432929d37d60158aca21ad4c ]
'./test_progs -t test_local_storage' reported a splat:
[ 27.137569] =============================
[ 27.138122] [ BUG: Invalid wait context ]
[ 27.138650] 6.5.0-03980-gd11ae1b16b0a #247 Tainted: G O
[ 27.139542] -----------------------------
[ 27.140106] test_progs/1729 is trying to lock:
[ 27.140713] ffff8883ef047b88 (stock_lock){-.-.}-{3:3}, at: local_lock_acquire+0x9/0x130
[ 27.141834] other info that might help us debug this:
[ 27.142437] context-{5:5}
[ 27.142856] 2 locks held by test_progs/1729:
[ 27.143352] #0: ffffffff84bcd9c0 (rcu_read_lock){....}-{1:3}, at: rcu_lock_acquire+0x4/0x40
[ 27.144492] #1: ffff888107deb2c0 (&storage->lock){..-.}-{2:2}, at: bpf_local_storage_update+0x39e/0x8e0
[ 27.145855] stack backtrace:
[ 27.146274] CPU: 0 PID: 1729 Comm: test_progs Tainted: G O 6.5.0-03980-gd11ae1b16b0a #247
[ 27.147550] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014
[ 27.149127] Call Trace:
[ 27.149490] <TASK>
[ 27.149867] dump_stack_lvl+0x130/0x1d0
[ 27.152609] dump_stack+0x14/0x20
[ 27.153131] __lock_acquire+0x1657/0x2220
[ 27.153677] lock_acquire+0x1b8/0x510
[ 27.157908] local_lock_acquire+0x29/0x130
[ 27.159048] obj_cgroup_charge+0xf4/0x3c0
[ 27.160794] slab_pre_alloc_hook+0x28e/0x2b0
[ 27.161931] __kmem_cache_alloc_node+0x51/0x210
[ 27.163557] __kmalloc+0xaa/0x210
[ 27.164593] bpf_map_kzalloc+0xbc/0x170
[ 27.165147] bpf_selem_alloc+0x130/0x510
[ 27.166295] bpf_local_storage_update+0x5aa/0x8e0
[ 27.167042] bpf_fd_sk_storage_update_elem+0xdb/0x1a0
[ 27.169199] bpf_map_update_value+0x415/0x4f0
[ 27.169871] map_update_elem+0x413/0x550
[ 27.170330] __sys_bpf+0x5e9/0x640
[ 27.174065] __x64_sys_bpf+0x80/0x90
[ 27.174568] do_syscall_64+0x48/0xa0
[ 27.175201] entry_SYSCALL_64_after_hwframe+0x6e/0xd8
[ 27.175932] RIP: 0033:0x7effb40e41ad
[ 27.176357] Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 90 f3 0f 1e fa 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d8
[ 27.179028] RSP: 002b:00007ffe64c21fc8 EFLAGS: 00000202 ORIG_RAX: 0000000000000141
[ 27.180088] RAX: ffffffffffffffda RBX: 00007ffe64c22768 RCX: 00007effb40e41ad
[ 27.181082] RDX: 0000000000000020 RSI: 00007ffe64c22008 RDI: 0000000000000002
[ 27.182030] RBP: 00007ffe64c21ff0 R08: 0000000000000000 R09: 00007ffe64c22788
[ 27.183038] R10: 0000000000000064 R11: 0000000000000202 R12: 0000000000000000
[ 27.184006] R13: 00007ffe64c22788 R14: 00007effb42a1000 R15: 0000000000000000
[ 27.184958] </TASK>It complains about acquiring a local_lock while holding a raw_spin_lock. It means it should not allocate memory while holding a raw_spin_lock since it is not safe for RT.
raw_spin_lock is needed because bpf_local_storage supports tracing context. In particular for task local storage, it is easy to get a "current" task PTR_TO_BTF_ID in tracing bpf prog. However, task (and cgroup) local storage has already been moved to bpf mem allocator which can be used after raw_spin_lock.
The splat is for the sk storage. For sk (and inode) storage, it has not been moved to bpf mem allocator. Using raw_spin_lock or not, kzalloc(GFP_ATOMIC) could theoretically be unsafe in tracing context. However, the local storage helper requires a verifier accepted sk pointer (PTR_TO_BTF_ID), it is hypothetical if that (mean running a bpf prog in a kzalloc unsafe context and also able to hold a verifier accepted sk pointer) could happen.
This patch avoids kzalloc after raw_spin_lock to silent the splat. There is an existing kzalloc before the raw_spin_lock. At that point, a kzalloc is very likely required because a lookup has just been done before. Thus, this patch always does the kzalloc before acquiring the raw_spin_lock and remove the later kzalloc usage after the raw_spin_lock. After this change, it will have a charge and then uncharge during the syscall bpf_map_update_elem() code path. This patch opts for simplicity and not continue the old optimization to save one charge and uncharge.
This issue is dated back to the very first commit of bpf_sk_storage which had been refactored multiple times to create task, inode, and cgroup storage. This patch uses a Fixes tag with a more recent commit that should be easier to do backport.
--- kernel/bpf/bpf_local_storage.c | 47 ++++++++++------------------------ 1 file changed, 14 insertions(+), 33 deletions(-)
kernel/bpf/bpf_local_storage.c +14 -33
@@ -553,7 +553,7 @@ bpf_local_storage_update(void *owner, struct bpf_local_storage_map *smap, void *value, u64 map_flags, gfp_t gfp_flags) { struct bpf_local_storage_data *old_sdata = NULL; -struct bpf_local_storage_elem *selem =NULL ; +struct bpf_local_storage_elem *alloc_selem, *selem =NULL ;struct bpf_local_storage *local_storage;unsigned long flags;int err;
@@ -607,11 +607,12 @@ bpf_local_storage_update(void *owner, struct bpf_local_storage_map *smap, } } -if (gfp_flags ==GFP_KERNEL ) { - selem =bpf_selem_alloc (smap, owner, value, true, gfp_flags); -if (!selem) -return ERR_PTR (-ENOMEM ); - } +/* A lookup has just been done before and concluded a new selem is +* needed. The chance of an unnecessary alloc is unlikely. +*/ + alloc_selem = selem =bpf_selem_alloc (smap, owner, value, true, gfp_flags); +if (!alloc_selem) +return ERR_PTR (-ENOMEM );raw_spin_lock_irqsave (&local_storage->lock, flags);
@@ -623,13 +624,13 @@ bpf_local_storage_update(void *owner, struct bpf_local_storage_map *smap,* simple. */ err = -EAGAIN ; - goto unlock_err; + goto unlock; } old_sdata =bpf_local_storage_lookup (local_storage, smap, false); err =check_flags (old_sdata, map_flags);if (err) - goto unlock_err; + goto unlock;if (old_sdata && (map_flags &BPF_F_LOCK )) { copy_map_value_locked(&smap->map, old_sdata->data, value,
@@ -638,23 +639,7 @@ bpf_local_storage_update(void *owner, struct bpf_local_storage_map *smap, goto unlock; } -if (gfp_flags !=GFP_KERNEL ) { -/* local_storage->lock is held. Hence, we are sure -* we can unlink and uncharge the old_sdata successfully -* later. Hence, instead of charging the new selem now -* and then uncharge the old selem later (which may cause -* a potential but unnecessary charge failure), avoid taking -* a charge at all here (the "!old_sdata" check) and the -* old_sdata will not be uncharged later during -* bpf_selem_unlink_storage_nolock(). -*/ - selem =bpf_selem_alloc (smap, owner, value, !old_sdata, gfp_flags); -if (!selem) { - err = -ENOMEM ; - goto unlock_err; - } - } - + alloc_selem =NULL ;/* First, link the new selem to the map */ bpf_selem_link_map (smap, selem);
@@ -665,20 +650,16 @@ bpf_local_storage_update(void *owner, struct bpf_local_storage_map *smap,if (old_sdata) {bpf_selem_unlink_map (SELEM (old_sdata));bpf_selem_unlink_storage_nolock (local_storage,SELEM (old_sdata), - false, false); + true, false); } unlock:raw_spin_unlock_irqrestore (&local_storage->lock, flags); -return SDATA (selem); - -unlock_err: -raw_spin_unlock_irqrestore (&local_storage->lock, flags); -if (selem) { +if (alloc_selem) {mem_uncharge (smap, owner, smap->elem_size); -bpf_selem_free (selem, smap, true); +bpf_selem_free (alloc_selem, smap, true); } -return ERR_PTR (err); +return err ?ERR_PTR (err) :SDATA (selem); }static u16 bpf_local_storage_cache_idx_get (struct bpf_local_storage_cache *cache)
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 161/285 bpf: bpf_sk_storage: Fix the missing uncharge in sk_omem_alloc
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Martin KaFai Lau <[email protected]>
[ Upstream commit 55d49f750b1cb1f177fb1b00ae02cba4613bcfb7 ]
The commit c83597fa5dc6 ("bpf: Refactor some inode/task/sk storage functions for reuse"), refactored the bpf_{sk,task,inode}_storage_free() into bpf_local_storage_unlink_nolock() which then later renamed to bpf_local_storage_destroy(). The commit accidentally passed the "bool uncharge_mem = false" argument to bpf_selem_unlink_storage_nolock() which then stopped the uncharge from happening to the sk->sk_omem_alloc.
This missing uncharge only happens when the sk is going away (during __sk_destruct).
This patch fixes it by always passing "uncharge_mem = true". It is a noop to the task/inode/cgroup storage because they do not have the map_local_storage_(un)charge enabled in the map_ops. A followup patch will be done in bpf-next to remove the uncharge_mem argument.
A selftest is added in the next patch.
--- kernel/bpf/bpf_local_storage.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/bpf/bpf_local_storage.c +1 -1
@@ -760,7 +760,7 @@ void bpf_local_storage_destroy(struct bpf_local_storage *local_storage)* of the loop will set the free_cgroup_storage to true. */ free_storage =bpf_selem_unlink_storage_nolock ( - local_storage, selem, false, true); + local_storage, selem, true, true); }raw_spin_unlock_irqrestore (&local_storage->lock, flags);
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 162/285 netfilter: nftables: exthdr: fix 4-byte stack OOB write
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Westphal <[email protected]>
[ Upstream commit fd94d9dadee58e09b49075240fe83423eb1dcd36 ]
If priv->len is a multiple of 4, then dst[len / 4] can write past the destination array which leads to stack corruption.
This construct is necessary to clean the remainder of the register in case ->len is NOT a multiple of the register size, so make it conditional just like nft_payload.c does.
The bug was added in 4.1 cycle and then copied/inherited when tcp/sctp and ip option support was added.
Bug reported by Zero Day Initiative project (ZDI-CAN-21950, ZDI-CAN-21951, ZDI-CAN-21961).
--- net/netfilter/nft_exthdr.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-)
net/netfilter/nft_exthdr.c +14 -8
@@ -35,6 +35,14 @@ static unsigned int optlen(const u8 *opt, unsigned int offset)return opt[offset +1 ]; } +static int nft_skb_copy_to_reg (const struct sk_buff *skb,int offset,u32 *dest,unsigned int len) +{ +if (len %NFT_REG32_SIZE ) + dest[len /NFT_REG32_SIZE ] =0 ; + +return skb_copy_bits (skb, offset, dest, len); +} +static void nft_exthdr_ipv6_eval (const struct nft_expr *expr,struct nft_regs *regs,const struct nft_pktinfo *pkt)
@@ -56,8 +64,7 @@ static void nft_exthdr_ipv6_eval(const struct nft_expr *expr, } offset += priv->offset; - dest[priv->len /NFT_REG32_SIZE ] =0 ; -if (skb_copy_bits (pkt->skb, offset, dest, priv->len) <0 ) +if (nft_skb_copy_to_reg (pkt->skb, offset, dest, priv->len) <0 ) goto err;return ; err:
@@ -153,8 +160,7 @@ static void nft_exthdr_ipv4_eval(const struct nft_expr *expr, } offset += priv->offset; - dest[priv->len /NFT_REG32_SIZE ] =0 ; -if (skb_copy_bits (pkt->skb, offset, dest, priv->len) <0 ) +if (nft_skb_copy_to_reg (pkt->skb, offset, dest, priv->len) <0 ) goto err;return ; err:
@@ -210,7 +216,8 @@ static void nft_exthdr_tcp_eval(const struct nft_expr *expr,if (priv->flags &NFT_EXTHDR_F_PRESENT ) { *dest =1 ; }else { - dest[priv->len /NFT_REG32_SIZE ] =0 ; +if (priv->len %NFT_REG32_SIZE ) + dest[priv->len /NFT_REG32_SIZE ] =0 ;memcpy (dest, opt + offset, priv->len); }
@@ -388,9 +395,8 @@ static void nft_exthdr_sctp_eval(const struct nft_expr *expr, offset + ntohs(sch->length) > pkt->skb->len) break; - dest[priv->len /NFT_REG32_SIZE ] =0 ; -if (skb_copy_bits (pkt->skb, offset + priv->offset, - dest, priv->len) <0 ) +if (nft_skb_copy_to_reg (pkt->skb, offset + priv->offset, + dest, priv->len) <0 )break ;return ; }
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 163/285 netfilter: nfnetlink_osf: avoid OOB read
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wander Lairson Costa <[email protected]>
[ Upstream commit f4f8a7803119005e87b716874bec07c751efafec ]
The opt_num field is controlled by user mode and is not currently validated inside the kernel. An attacker can take advantage of this to trigger an OOB read and potentially leak information.
BUG: KASAN: slab-out-of-bounds in nf_osf_match_one+0xbed/0xd10 net/netfilter/nfnetlink_osf.c:88 Read of size 2 at addr ffff88804bc64272 by task poc/6431 CPU: 1 PID: 6431 Comm: poc Not tainted 6.0.0-rc4 #1 Call Trace: nf_osf_match_one+0xbed/0xd10 net/netfilter/nfnetlink_osf.c:88 nf_osf_find+0x186/0x2f0 net/netfilter/nfnetlink_osf.c:281 nft_osf_eval+0x37f/0x590 net/netfilter/nft_osf.c:47 expr_call_ops_eval net/netfilter/nf_tables_core.c:214 nft_do_chain+0x2b0/0x1490 net/netfilter/nf_tables_core.c:264 nft_do_chain_ipv4+0x17c/0x1f0 net/netfilter/nft_chain_filter.c:23 [..]
Also add validation to genre, subtype and version fields.
--- net/netfilter/nfnetlink_osf.c | 8 ++++++++ 1 file changed, 8 insertions(+)
net/netfilter/nfnetlink_osf.c +8 -0
@@ -315,6 +315,14 @@ static int nfnl_osf_add_callback(struct sk_buff *skb, f =nla_data (osf_attrs[OSF_ATTR_FINGER ]); +if (f->opt_num >ARRAY_SIZE (f->opt)) +return -EINVAL ; + +if (!memchr (f->genre,0 ,MAXGENRELEN ) || + !memchr (f->subtype,0 ,MAXGENRELEN ) || + !memchr (f->version,0 ,MAXGENRELEN )) +return -EINVAL ; + kf =kmalloc (sizeof (struct nf_osf_finger ),GFP_KERNEL );if (!kf)return -ENOMEM ;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 164/285 netfilter: nft_set_rbtree: skip sync GC for new elements in this transaction
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pablo Neira Ayuso <[email protected]>
[ Upstream commit 2ee52ae94baabf7ee09cf2a8d854b990dac5d0e4 ]
New elements in this transaction might expired before such transaction ends. Skip sync GC for such elements otherwise commit path might walk over an already released object. Once transaction is finished, async GC will collect such expired element.
--- net/netfilter/nft_set_rbtree.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
net/netfilter/nft_set_rbtree.c +6 -2
@@ -312,6 +312,7 @@ static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set,struct nft_rbtree_elem *rbe, *rbe_le =NULL , *rbe_ge =NULL ;struct rb_node *node, *next, *parent, **p, *first =NULL ;struct nft_rbtree *priv =nft_set_priv (set); +u8 cur_genmask =nft_genmask_cur (net);u8 genmask =nft_genmask_next (net);int d, err;
@@ -357,8 +358,11 @@ static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set,if (!nft_set_elem_active (&rbe->ext, genmask))continue ; -/* perform garbage collection to avoid bogus overlap reports. */ -if (nft_set_elem_expired (&rbe->ext)) { +/* perform garbage collection to avoid bogus overlap reports +* but skip new elements in this transaction. +*/ +if (nft_set_elem_expired (&rbe->ext) && +nft_set_elem_active (&rbe->ext, cur_genmask)) { err =nft_rbtree_gc_elem (set, priv, rbe, genmask);if (err <0 )return err;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 165/285 netfilter: nf_tables: Unbreak audit log reset
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pablo Neira Ayuso <[email protected]>
[ Upstream commit 9b5ba5c9c5109bf89dc64a3f4734bd125d1ce52e ]
Deliver audit log from __nf_tables_dump_rules(), table dereference at the end of the table list loop might point to the list head, leading to this crash.
[ 4137.407349] BUG: unable to handle page fault for address: 00000000001f3c50 [ 4137.407357] #PF: supervisor read access in kernel mode [ 4137.407359] #PF: error_code(0x0000) - not-present page [ 4137.407360] PGD 0 P4D 0 [ 4137.407363] Oops: 0000 [#1] PREEMPT SMP PTI [ 4137.407365] CPU: 4 PID: 500177 Comm: nft Not tainted 6.5.0+ #277 [ 4137.407369] RIP: 0010:string+0x49/0xd0 [ 4137.407374] Code: ff 77 36 45 89 d1 31 f6 49 01 f9 66 45 85 d2 75 19 eb 1e 49 39 f8 76 02 88 07 48 83 c7 01 83 c6 01 48 83 c2 01 4c 39 cf 74 07 <0f> b6 02 84 c0 75 e2 4c 89 c2 e9 58 e5 ff ff 48 c7 c0 0e b2 ff 81 [ 4137.407377] RSP: 0018:ffff8881179737f0 EFLAGS: 00010286 [ 4137.407379] RAX: 00000000001f2c50 RBX: ffff888117973848 RCX: ffff0a00ffffff04 [ 4137.407380] RDX: 00000000001f3c50 RSI: 0000000000000000 RDI: 0000000000000000 [ 4137.407381] RBP: 0000000000000000 R08: 0000000000000000 R09: 00000000ffffffff [ 4137.407383] R10: ffffffffffffffff R11: ffff88813584d200 R12: 0000000000000000 [ 4137.407384] R13: ffffffffa15cf709 R14: 0000000000000000 R15: ffffffffa15cf709 [ 4137.407385] FS: 00007fcfc18bb580(0000) GS:ffff88840e700000(0000) knlGS:0000000000000000 [ 4137.407387] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 4137.407388] CR2: 00000000001f3c50 CR3: 00000001055b2001 CR4: 00000000001706e0 [ 4137.407390] Call Trace: [ 4137.407392] <TASK> [ 4137.407393] ? __die+0x1b/0x60 [ 4137.407397] ? page_fault_oops+0x6b/0xa0 [ 4137.407399] ? exc_page_fault+0x60/0x120 [ 4137.407403] ? asm_exc_page_fault+0x22/0x30 [ 4137.407408] ? string+0x49/0xd0 [ 4137.407410] vsnprintf+0x257/0x4f0 [ 4137.407414] kvasprintf+0x3e/0xb0 [ 4137.407417] kasprintf+0x3e/0x50 [ 4137.407419] nf_tables_dump_rules+0x1c0/0x360 [nf_tables] [ 4137.407439] ? __alloc_skb+0xc3/0x170 [ 4137.407442] netlink_dump+0x170/0x330 [ 4137.407447] __netlink_dump_start+0x227/0x300 [ 4137.407449] nf_tables_getrule+0x205/0x390 [nf_tables]
Deliver audit log only once at the end of the rule dump+reset for consistency with the set dump+reset.
Ensure audit reset access to table under rcu read side lock. The table list iteration holds rcu read lock side, but recent audit code dereferences table object out of the rcu read lock side.
--- net/netfilter/nf_tables_api.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
net/netfilter/nf_tables_api.c +6 -5
@@ -3480,6 +3480,10 @@ static int __nf_tables_dump_rules(struct sk_buff *skb, cont_skip: (*idx)++; } + +if (reset && *idx) +audit_log_rule_reset (table, cb->seq, *idx); +return 0 ; }
@@ -3540,9 +3544,6 @@ static int nf_tables_dump_rules(struct sk_buff *skb, done:rcu_read_unlock (); -if (reset && idx > cb->args[0 ]) -audit_log_rule_reset (table, cb->seq, idx - cb->args[0 ]); - cb->args[0 ] = idx;return skb->len; }
@@ -5757,8 +5758,6 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)if (!args.iter.err && args.iter.count == cb->args[0 ]) args.iter.err =nft_set_catchall_dump (net, skb, set, reset, cb->seq); -rcu_read_unlock (); -nla_nest_end (skb, nest);nlmsg_end (skb, nlh);
@@ -5766,6 +5765,8 @@ static int nf_tables_dump_set(struct sk_buff *skb, struct netlink_callback *cb)audit_log_nft_set_reset (table, cb->seq, args.iter.count - args.iter.skip); +rcu_read_unlock (); +if (args.iter.err && args.iter.err != -EMSGSIZE )return args.iter.err;if (args.iter.count == cb->args[0 ])
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 166/285 net: phy: Provide Module 4 KSZ9477 errata (DS80000754C)
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lukasz Majewski <[email protected]>
[ Upstream commit 08c6d8bae48c2c28f7017d7b61b5d5a1518ceb39 ]
The KSZ9477 errata points out (in 'Module 4') the link up/down problems when EEE (Energy Efficient Ethernet) is enabled in the device to which the KSZ9477 tries to auto negotiate.
The suggested workaround is to clear advertisement of EEE for PHYs in this chip driver.
To avoid regressions with other switch ICs the new MICREL_NO_EEE flag has been introduced.
Moreover, the in-register disablement of MMD_DEVICE_ID_EEE_ADV.MMD_EEE_ADV MMD register is removed, as this code is both; now executed too late (after previous rework of the PHY and DSA for KSZ switches) and not required as setting all members of eee_broken_modes bit field prevents the KSZ9477 from advertising EEE.
--- drivers/net/dsa/microchip/ksz_common.c | 16 +++++++++++++++- drivers/net/phy/micrel.c | 9 ++++++--- include/linux/micrel_phy.h | 1 + 3 files changed, 22 insertions(+), 4 deletions(-)
drivers/net/dsa/microchip/ksz_common.c +15 -1
@@ -2337,13 +2337,27 @@ static u32 ksz_get_phy_flags(struct dsa_switch *ds, int port) {struct ksz_device *dev = ds->priv; -if (dev->chip_id ==KSZ8830_CHIP_ID ) { +switch (dev->chip_id) { +case KSZ8830_CHIP_ID :/* Silicon Errata Sheet (DS80000830A): * Port 1 does not work with LinkMD Cable-Testing. * Port 1 does not respond to received PAUSE control frames. */ if (!port)return MICREL_KSZ8_P1_ERRATA ; +break ; +case KSZ9477_CHIP_ID : +/* KSZ9477 Errata DS80000754C +* +* Module 4: Energy Efficient Ethernet (EEE) feature select must +* be manually disabled +* The EEE feature is enabled by default, but it is not fully +* operational. It must be manually disabled through register +* controls. If not disabled, the PHY ports can auto-negotiate +* to enable EEE, and this feature can cause link drops when +* linked to another device supporting EEE. +*/ +return MICREL_NO_EEE ; }return 0 ;
drivers/net/phy/micrel.c +6 -3
@@ -1800,9 +1800,6 @@ static const struct ksz9477_errata_write ksz9477_errata_writes[] = {/* Transmit waveform amplitude can be improved (1000BASE-T, 100BASE-TX, 10BASE-Te) */ {0x1c, 0x04, 0x00d0}, -/* Energy Efficient Ethernet (EEE) feature select must be manually disabled */ - {0x07, 0x3c, 0x0000}, -/* Register settings are required to meet data sheet supply current specifications */ {0x1c, 0x13, 0x6eff}, {0x1c, 0x14, 0xe6ff},
@@ -1847,6 +1844,12 @@ static int ksz9477_config_init(struct phy_device *phydev)return err; } +/* According to KSZ9477 Errata DS80000754C (Module 4) all EEE modes +* in this switch shall be regarded as broken. +*/ +if (phydev->dev_flags &MICREL_NO_EEE ) + phydev->eee_broken_modes =-1 ; + err =genphy_restart_aneg (phydev);if (err)return err;
include/linux/micrel_phy.h +1 -0
@@ -44,6 +44,7 @@#define MICREL_PHY_50MHZ_CLK BIT(0)#define MICREL_PHY_FXEN BIT(1)#define MICREL_KSZ8_P1_ERRATA BIT(2) +#define MICREL_NO_EEE BIT(3)#define MICREL_KSZ9021_EXTREG_CTRL 0xB#define MICREL_KSZ9021_EXTREG_DATA_WRITE 0xC
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 167/285 net: hns3: fix tx timeout issue
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jian Shen <[email protected]>
[ Upstream commit 61a1deacc3d4fd3d57d7fda4d935f7f7503e8440 ]
Currently, the driver knocks the ring doorbell before updating the ring->last_to_use in tx flow. if the hardware transmiting packet and napi poll scheduling are fast enough, it may get the old ring->last_to_use in drivers' napi poll.
In this case, the driver will think the tx is not completed, and return directly without clear the flag __QUEUE_STATE_STACK_XOFF, which may cause tx timeout.
--- drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-)
drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +12 -5
@@ -2102,8 +2102,12 @@ static void hns3_tx_doorbell(struct hns3_enet_ring *ring, int num,*/ if (test_bit (HNS3_NIC_STATE_TX_PUSH_ENABLE , &priv->state) && num && !ring->pending_buf && num <=HNS3_MAX_PUSH_BD_NUM && doorbell) { +/* This smp_store_release() pairs with smp_load_aquire() in +* hns3_nic_reclaim_desc(). Ensure that the BD valid bit +* is updated. +*/ +smp_store_release (&ring->last_to_use, ring->next_to_use);hns3_tx_push_bd (ring, num); -WRITE_ONCE (ring->last_to_use, ring->next_to_use);return ; }
@@ -2114,6 +2118,11 @@ static void hns3_tx_doorbell(struct hns3_enet_ring *ring, int num,return ; } +/* This smp_store_release() pairs with smp_load_aquire() in +* hns3_nic_reclaim_desc(). Ensure that the BD valid bit is updated. +*/ +smp_store_release (&ring->last_to_use, ring->next_to_use); +if (ring->tqp->mem_base)hns3_tx_mem_doorbell (ring);else
@@ -2121,7 +2130,6 @@ static void hns3_tx_doorbell(struct hns3_enet_ring *ring, int num, ring->tqp->io_base + HNS3_RING_TX_RING_TAIL_REG); ring->pending_buf =0 ; -WRITE_ONCE (ring->last_to_use, ring->next_to_use); } static void hns3_tsyn(struct net_device *netdev, struct sk_buff *skb,
@@ -3562,9 +3570,8 @@ static void hns3_reuse_buffer(struct hns3_enet_ring *ring, int i)static bool hns3_nic_reclaim_desc (struct hns3_enet_ring *ring,int *bytes,int *pkts,int budget) { -/* pair with ring->last_to_use update in hns3_tx_doorbell(), -* smp_store_release() is not used in hns3_tx_doorbell() because -* the doorbell operation already have the needed barrier operation. +/* This smp_load_acquire() pairs with smp_store_release() in +* hns3_tx_doorbell(). */ int ltu =smp_load_acquire (&ring->last_to_use);int ntc = ring->next_to_clean;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 168/285 net: hns3: fix byte order conversion issue in hclge_dbg_fd_tcam_read()
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hao Chen <[email protected]>
[ Upstream commit efccf655e99b6907ca07a466924e91805892e7d3 ]
req1->tcam_data is defined as "u8 tcam_data[8]", and we convert it as (u32 *) without considerring byte order conversion,
it may result in printing wrong data for tcam_data.
Convert tcam_data to (__le32 *) first to fix it.
--- .../ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_debugfs.c +7 -7
@@ -1519,7 +1519,7 @@ static int hclge_dbg_fd_tcam_read(struct hclge_dev *hdev, bool sel_x,struct hclge_desc desc[3 ];int pos =0 ;int ret, i; -u32 *req; +__le32 *req;hclge_cmd_setup_basic_desc (&desc[0 ],HCLGE_OPC_FD_TCAM_OP , true); desc[0 ].flag |=cpu_to_le16 (HCLGE_COMM_CMD_FLAG_NEXT );
@@ -1544,22 +1544,22 @@ static int hclge_dbg_fd_tcam_read(struct hclge_dev *hdev, bool sel_x, tcam_msg.loc);/* tcam_data0 ~ tcam_data1 */ - req = (u32 *)req1->tcam_data; + req = (__le32 *)req1->tcam_data;for (i =0 ; i <2 ; i++) pos +=scnprintf (tcam_buf + pos,HCLGE_DBG_TCAM_BUF_SIZE - pos, -"%08x\n" , *req++); +"%08x\n" ,le32_to_cpu (*req++));/* tcam_data2 ~ tcam_data7 */ - req = (u32 *)req2->tcam_data; + req = (__le32 *)req2->tcam_data;for (i =0 ; i <6 ; i++) pos +=scnprintf (tcam_buf + pos,HCLGE_DBG_TCAM_BUF_SIZE - pos, -"%08x\n" , *req++); +"%08x\n" ,le32_to_cpu (*req++));/* tcam_data8 ~ tcam_data12 */ - req = (u32 *)req3->tcam_data; + req = (__le32 *)req3->tcam_data;for (i =0 ; i <5 ; i++) pos +=scnprintf (tcam_buf + pos,HCLGE_DBG_TCAM_BUF_SIZE - pos, -"%08x\n" , *req++); +"%08x\n" ,le32_to_cpu (*req++));return ret; }
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 169/285 net: hns3: fix debugfs concurrency issue between kfree buffer and read
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hao Chen <[email protected]>
[ Upstream commit c295160b1d95e885f1af4586a221cb221d232d10 ]
Now in hns3_dbg_uninit(), there may be concurrency between kfree buffer and read, it may result in memory error.
Moving debugfs_remove_recursive() in front of kfree buffer to ensure they don't happen at the same time.
--- drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/net/ethernet/hisilicon/hns3/hns3_debugfs.c +4 -3
@@ -1411,9 +1411,9 @@ int hns3_dbg_init(struct hnae3_handle *handle)return 0 ; out: -mutex_destroy (&handle->dbgfs_lock);debugfs_remove_recursive (handle->hnae3_dbgfs); handle->hnae3_dbgfs =NULL ; +mutex_destroy (&handle->dbgfs_lock);return ret; }
@@ -1421,6 +1421,9 @@ void hns3_dbg_uninit(struct hnae3_handle *handle) {u32 i; +debugfs_remove_recursive (handle->hnae3_dbgfs); + handle->hnae3_dbgfs =NULL ; +for (i =0 ; i <ARRAY_SIZE (hns3_dbg_cmd); i++)if (handle->dbgfs_buf[i]) {kvfree (handle->dbgfs_buf[i]);
@@ -1428,8 +1431,6 @@ void hns3_dbg_uninit(struct hnae3_handle *handle) }mutex_destroy (&handle->dbgfs_lock); -debugfs_remove_recursive (handle->hnae3_dbgfs); - handle->hnae3_dbgfs =NULL ; }void hns3_dbg_register_debugfs (const char *debugfs_dir_name)
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 170/285 net: hns3: fix invalid mutex between tc qdisc and dcb ets command issue
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jijie Shao <[email protected]>
[ Upstream commit fa5564945f7d15ae2390b00c08b6abaef0165cda ]
We hope that tc qdisc and dcb ets commands can not be used crosswise. If we want to use any of the commands to configure tc,
We must use the other command to clear the existing configuration.
However, when we configure a single tc with tc qdisc, we can still configure it with dcb ets.
Because we use mqprio_active as the tag of tc qdisc configuration, but with dcb ets, we do not check mqprio_active.
This patch fix this issue by check mqprio_active before executing the dcb ets command. and add dcb_ets_active to replace HCLGE_FLAG_DCB_ENABLE and HCLGE_FLAG_MQPRIO_ENABLE at the hclge layer,
--- drivers/net/ethernet/hisilicon/hns3/hnae3.h | 1 + .../hisilicon/hns3/hns3pf/hclge_dcb.c | 20 +++++-------------- .../hisilicon/hns3/hns3pf/hclge_main.c | 5 +++-- .../hisilicon/hns3/hns3pf/hclge_main.h | 2 -- 4 files changed, 9 insertions(+), 19 deletions(-)
drivers/net/ethernet/hisilicon/hns3/hnae3.h +1 -0
@@ -814,6 +814,7 @@ struct hnae3_tc_info {u8 max_tc;/* Total number of TCs */ u8 num_tc;/* Total number of enabled TCs */ bool mqprio_active; +bool dcb_ets_active; };#define HNAE3_MAX_DSCP 64
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_dcb.c +5 -15
@@ -259,7 +259,7 @@ static int hclge_ieee_setets(struct hnae3_handle *h, struct ieee_ets *ets)int ret;if (!(hdev->dcbx_cap &DCB_CAP_DCBX_VER_IEEE ) || - hdev->flag &HCLGE_FLAG_MQPRIO_ENABLE ) + h->kinfo.tc_info.mqprio_active)return -EINVAL ; ret =hclge_ets_validate (hdev, ets, &num_tc, &map_changed);
@@ -275,10 +275,7 @@ static int hclge_ieee_setets(struct hnae3_handle *h, struct ieee_ets *ets) }hclge_tm_schd_info_update (hdev, num_tc); -if (num_tc >1 ) - hdev->flag |=HCLGE_FLAG_DCB_ENABLE ; -else - hdev->flag &= ~HCLGE_FLAG_DCB_ENABLE ; + h->kinfo.tc_info.dcb_ets_active = num_tc >1 ; ret =hclge_ieee_ets_to_tm_info (hdev, ets);if (ret)
@@ -487,7 +484,7 @@ static u8 hclge_getdcbx(struct hnae3_handle *h)struct hclge_vport *vport =hclge_get_vport (h);struct hclge_dev *hdev = vport->back; -if (hdev->flag &HCLGE_FLAG_MQPRIO_ENABLE ) +if (h->kinfo.tc_info.mqprio_active)return 0 ;return hdev->dcbx_cap;
@@ -611,7 +608,8 @@ static int hclge_setup_tc(struct hnae3_handle *h,if (!test_bit (HCLGE_STATE_NIC_REGISTERED , &hdev->state))return -EBUSY ; -if (hdev->flag &HCLGE_FLAG_DCB_ENABLE ) + kinfo = &vport->nic.kinfo; +if (kinfo->tc_info.dcb_ets_active)return -EINVAL ; ret =hclge_mqprio_qopt_check (hdev, mqprio_qopt);
@@ -625,7 +623,6 @@ static int hclge_setup_tc(struct hnae3_handle *h,if (ret)return ret; - kinfo = &vport->nic.kinfo;memcpy (&old_tc_info, &kinfo->tc_info,sizeof (old_tc_info));hclge_sync_mqprio_qopt (&kinfo->tc_info, mqprio_qopt); kinfo->tc_info.mqprio_active = tc >0 ;
@@ -634,13 +631,6 @@ static int hclge_setup_tc(struct hnae3_handle *h,if (ret) goto err_out; - hdev->flag &= ~HCLGE_FLAG_DCB_ENABLE ; - -if (tc >1 ) - hdev->flag |=HCLGE_FLAG_MQPRIO_ENABLE ; -else - hdev->flag &= ~HCLGE_FLAG_MQPRIO_ENABLE ; -return hclge_notify_init_up (hdev); err_out:
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +3 -2
@@ -11026,6 +11026,7 @@ static void hclge_get_mdix_mode(struct hnae3_handle *handle,static void hclge_info_show (struct hclge_dev *hdev) { +struct hnae3_handle *handle = &hdev->vport->nic;struct device *dev = &hdev->pdev->dev;dev_info (dev,"PF info begin:\n" );
@@ -11042,9 +11043,9 @@ static void hclge_info_show(struct hclge_dev *hdev)dev_info (dev,"This is %s PF\n" , hdev->flag &HCLGE_FLAG_MAIN ?"main" :"not main" );dev_info (dev,"DCB %s\n" , - hdev->flag &HCLGE_FLAG_DCB_ENABLE ?"enable" :"disable" ); + handle->kinfo.tc_info.dcb_ets_active ?"enable" :"disable" );dev_info (dev,"MQPRIO %s\n" , - hdev->flag &HCLGE_FLAG_MQPRIO_ENABLE ?"enable" :"disable" ); + handle->kinfo.tc_info.mqprio_active ?"enable" :"disable" );dev_info (dev,"Default tx spare buffer size: %u\n" , hdev->tx_spare_buf_size);
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.h +0 -2
@@ -919,8 +919,6 @@ struct hclge_dev {#define HCLGE_FLAG_MAIN BIT(0)#define HCLGE_FLAG_DCB_CAPABLE BIT(1) -#define HCLGE_FLAG_DCB_ENABLE BIT(2) -#define HCLGE_FLAG_MQPRIO_ENABLE BIT(3)u32 flag;u32 pkt_buf_size;/* Total pf buf size for tx/rx */
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 171/285 net: hns3: fix the port information display when sfp is absent
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yisen Zhuang <[email protected]>
[ Upstream commit 674d9591a32d01df75d6b5fffed4ef942a294376 ]
When sfp is absent or unidentified, the port type should be displayed as PORT_OTHERS, rather than PORT_FIBRE.
--- drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/net/ethernet/hisilicon/hns3/hns3_ethtool.c +3 -1
@@ -773,7 +773,9 @@ static int hns3_get_link_ksettings(struct net_device *netdev,hns3_get_ksettings (h, cmd);break ;case HNAE3_MEDIA_TYPE_FIBER : -if (module_type ==HNAE3_MODULE_TYPE_CR ) +if (module_type ==HNAE3_MODULE_TYPE_UNKNOWN ) + cmd->base.port =PORT_OTHER ; +else if (module_type ==HNAE3_MODULE_TYPE_CR ) cmd->base.port =PORT_DA ;else cmd->base.port =PORT_FIBRE ;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 172/285 net: hns3: remove GSO partial feature bit
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jie Wang <[email protected]>
[ Upstream commit 60326634f6c54528778de18bfef1e8a7a93b3771 ]
HNS3 NIC does not support GSO partial packets segmentation. Actually tunnel packets for example NvGRE packets segment offload and checksum offload is already supported. There is no need to keep gso partial feature bit. So this patch removes it.
--- drivers/net/ethernet/hisilicon/hns3/hns3_enet.c | 2 -- 1 file changed, 2 deletions(-)
drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +0 -2
@@ -3315,8 +3315,6 @@ static void hns3_set_default_feature(struct net_device *netdev) netdev->priv_flags |=IFF_UNICAST_FLT ; - netdev->gso_partial_features |=NETIF_F_GSO_GRE_CSUM ; - netdev->features |=NETIF_F_HW_VLAN_CTAG_FILTER |NETIF_F_HW_VLAN_CTAG_TX |NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_RXCSUM | NETIF_F_SG | NETIF_F_GSO |
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 173/285 net: enetc: distinguish error from valid pointers in enetc_fixup_clear_rss_rfs()
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vladimir Oltean <[email protected]>
[ Upstream commit 1b36955cc048c8ff6ba448dbf4be0e52f59f2963 ]
enetc_psi_create() returns an ERR_PTR() or a valid station interface pointer, but checking for the non-NULL quality of the return code blurs that difference away. So if enetc_psi_create() fails, we call enetc_psi_destroy() when we shouldn't. This will likely result in crashes, since enetc_psi_create() cleans up everything after itself when it returns an ERR_PTR().
--- drivers/net/ethernet/freescale/enetc/enetc_pf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/freescale/enetc/enetc_pf.c +1 -1
@@ -1402,7 +1402,7 @@ static void enetc_fixup_clear_rss_rfs(struct pci_dev *pdev)return ; si =enetc_psi_create (pdev); -if (si) +if (!IS_ERR (si))enetc_psi_destroy (pdev); } DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_FREESCALE, ENETC_DEV_ID_PF,
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 174/285 sh: boards: Fix CEU buffer size passed to dma_declare_coherent_memory()
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Petr Tesarik <[email protected]>
[ Upstream commit fb60211f377b69acffead3147578f86d0092a7a5 ]
In all these cases, the last argument to dma_declare_coherent_memory() is the buffer end address, but the expected value should be the size of the reserved region.
--- arch/sh/boards/mach-ap325rxa/setup.c | 2 +- arch/sh/boards/mach-ecovec24/setup.c | 6 ++---- arch/sh/boards/mach-kfr2r09/setup.c | 2 +- arch/sh/boards/mach-migor/setup.c | 2 +- arch/sh/boards/mach-se/7724/setup.c | 6 ++---- 5 files changed, 7 insertions(+), 11 deletions(-)
arch/sh/boards/mach-ap325rxa/setup.c +1 -1
@@ -531,7 +531,7 @@ static int __init ap325rxa_devices_setup(void)device_initialize (&ap325rxa_ceu_device.dev);dma_declare_coherent_memory (&ap325rxa_ceu_device.dev, ceu_dma_membase, ceu_dma_membase, - ceu_dma_membase +CEU_BUFFER_MEMORY_SIZE -1 ); +CEU_BUFFER_MEMORY_SIZE );platform_device_add (&ap325rxa_ceu_device);
arch/sh/boards/mach-ecovec24/setup.c +2 -4
@@ -1454,15 +1454,13 @@ static int __init arch_setup(void)device_initialize (&ecovec_ceu_devices[0 ]->dev);dma_declare_coherent_memory (&ecovec_ceu_devices[0 ]->dev, ceu0_dma_membase, ceu0_dma_membase, - ceu0_dma_membase + -CEU_BUFFER_MEMORY_SIZE -1 ); +CEU_BUFFER_MEMORY_SIZE );platform_device_add (ecovec_ceu_devices[0 ]);device_initialize (&ecovec_ceu_devices[1 ]->dev);dma_declare_coherent_memory (&ecovec_ceu_devices[1 ]->dev, ceu1_dma_membase, ceu1_dma_membase, - ceu1_dma_membase + -CEU_BUFFER_MEMORY_SIZE -1 ); +CEU_BUFFER_MEMORY_SIZE );platform_device_add (ecovec_ceu_devices[1 ]);gpiod_add_lookup_table (&cn12_power_gpiod_table);
arch/sh/boards/mach-kfr2r09/setup.c +1 -1
@@ -603,7 +603,7 @@ static int __init kfr2r09_devices_setup(void)device_initialize (&kfr2r09_ceu_device.dev);dma_declare_coherent_memory (&kfr2r09_ceu_device.dev, ceu_dma_membase, ceu_dma_membase, - ceu_dma_membase +CEU_BUFFER_MEMORY_SIZE -1 ); +CEU_BUFFER_MEMORY_SIZE );platform_device_add (&kfr2r09_ceu_device);
arch/sh/boards/mach-migor/setup.c +1 -1
@@ -604,7 +604,7 @@ static int __init migor_devices_setup(void)device_initialize (&migor_ceu_device.dev);dma_declare_coherent_memory (&migor_ceu_device.dev, ceu_dma_membase, ceu_dma_membase, - ceu_dma_membase +CEU_BUFFER_MEMORY_SIZE -1 ); +CEU_BUFFER_MEMORY_SIZE );platform_device_add (&migor_ceu_device);
arch/sh/boards/mach-se/7724/setup.c +2 -4
@@ -940,15 +940,13 @@ static int __init devices_setup(void)device_initialize (&ms7724se_ceu_devices[0 ]->dev);dma_declare_coherent_memory (&ms7724se_ceu_devices[0 ]->dev, ceu0_dma_membase, ceu0_dma_membase, - ceu0_dma_membase + -CEU_BUFFER_MEMORY_SIZE -1 ); +CEU_BUFFER_MEMORY_SIZE );platform_device_add (ms7724se_ceu_devices[0 ]);device_initialize (&ms7724se_ceu_devices[1 ]->dev);dma_declare_coherent_memory (&ms7724se_ceu_devices[1 ]->dev, ceu1_dma_membase, ceu1_dma_membase, - ceu1_dma_membase + -CEU_BUFFER_MEMORY_SIZE -1 ); +CEU_BUFFER_MEMORY_SIZE );platform_device_add (ms7724se_ceu_devices[1 ]); return platform_add_devices(ms7724se_devices,
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 175/285 sh: push-switch: Reorder cleanup operations to avoid use-after-free bug
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Duoming Zhou <[email protected]>
[ Upstream commit 246f80a0b17f8f582b2c0996db02998239057c65 ]
The original code puts flush_work() before timer_shutdown_sync() in switch_drv_remove(). Although we use flush_work() to stop the worker, it could be rescheduled in switch_timer(). As a result, a use-after-free bug can occur. The details are shown below:
(cpu 0) | (cpu 1)
switch_drv_remove() |
flush_work() |
... | switch_timer // timer
| schedule_work(&psw->work)
timer_shutdown_sync() |
... | switch_work_handler // worker
kfree(psw) // free |
| psw->state = 0 // useThis patch puts timer_shutdown_sync() before flush_work() to mitigate the bugs. As a result, the worker and timer will be stopped safely before the deallocate operations.
--- arch/sh/drivers/push-switch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/sh/drivers/push-switch.c +1 -1
@@ -101,8 +101,8 @@ static int switch_drv_remove(struct platform_device *pdev)device_remove_file (&pdev->dev, &dev_attr_switch);platform_set_drvdata (pdev,NULL ); -flush_work (&psw->work);timer_shutdown_sync (&psw->debounce); +flush_work (&psw->work);free_irq (irq, pdev);kfree (psw);
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 176/285 linux/export: fix reference to exported functions for parisc64
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Masahiro Yamada <[email protected]>
commit 08700ec705043eb0cee01b35cf5b9d63f0230d12 upstream.
John David Anglin reported parisc has been broken since commit ddb5cdbafaaa ("kbuild: generate KSYMTAB entries by modpost").
Like ia64, parisc64 uses a function descriptor. The function references must be prefixed with P%.
Also, symbols prefixed $$ from the library have the symbol type STT_LOPROC instead of STT_FUNC. They should be handled as functions too.
--- include/linux/export-internal.h | 2 ++ scripts/mod/modpost.c | 9 +++++++++ 2 files changed, 11 insertions(+)
include/linux/export-internal.h +2 -0
@@ -52,6 +52,8 @@#ifdef CONFIG_IA64 #define KSYM_FUNC (name) @fptr(name) +#elif defined(CONFIG_PARISC ) && defined(CONFIG_64BIT ) +#define KSYM_FUNC (name) P%name#else #define KSYM_FUNC (name) name#endif
scripts/mod/modpost.c +9 -0
@@ -1226,6 +1226,15 @@ static void check_export_symbol(struct m*/ s->is_func = (ELF_ST_TYPE (sym->st_info) ==STT_FUNC ); +/* +* For parisc64, symbols prefixed $$ from the library have the symbol type +* STT_LOPROC. They should be handled as functions too. +*/ +if (elf->hdr->e_ident[EI_CLASS ] ==ELFCLASS64 && + elf->hdr->e_machine ==EM_PARISC && +ELF_ST_TYPE (sym->st_info) ==STT_LOPROC ) + s->is_func = true; +if (match (secname,PATTERNS (INIT_SECTIONS )))warn ("%s: %s: EXPORT_SYMBOL used for init symbol. Remove __init or EXPORT_SYMBOL.\n" , mod->name, name);
Greg Kroah-Hartman
maintainerPATCH 177/285 watchdog: advantech_ec_wdt: fix Kconfig dependencies
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florent CARLI <[email protected]>
commit 6eb28a38f6478a650c7e76b2d6910669615d8a62 upstream.
This driver uses the WATCHDOG_CORE framework and ISA_BUS_API. This commit has these dependencies correctly selected.
--- drivers/watchdog/Kconfig | 2 ++ 1 file changed, 2 insertions(+)
drivers/watchdog/Kconfig +2 -0
@@ -1075,6 +1075,8 @@ config ADVANTECH_WDT config ADVANTECH_EC_WDT tristate "Advantech Embedded Controller Watchdog Timer" depends on X86 + select ISA_BUS_API + select WATCHDOG_CORE help This driver supports Advantech products with ITE based Embedded Controller. It does not support Advantech products with other ECs or without EC.
Greg Kroah-Hartman
maintainerPATCH 178/285 drm/amd/display: Temporary Disable MST DP Colorspace Property
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fangzhi Zuo <[email protected]>
commit 69a959610229ec31b534eaa5f6ec75965f321bed upstream.
Create MST colorsapce property for downstream device would trigger warning message "RIP: 0010:drm_mode_object_add+0x8e/0xa0 [drm]"
After driver is loaded and drm device is registered, create dp colorspace property triggers warning storm at WARN_ON(!dev->driver->load && dev->registered && !obj_free_cb);
Temporary disabling MST dp colorspace property for now.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +1 -1
@@ -7295,7 +7295,7 @@ void amdgpu_dm_connector_init_helper(strif (connector_type ==DRM_MODE_CONNECTOR_HDMIA ) {if (!drm_mode_create_hdmi_colorspace_property (&aconnector->base, supported_colorspaces))drm_connector_attach_colorspace_property (&aconnector->base); - }else if (connector_type == DRM_MODE_CONNECTOR_DisplayPort || + }else if ((connector_type == DRM_MODE_CONNECTOR_DisplayPort && !aconnector->mst_root) || connector_type == DRM_MODE_CONNECTOR_eDP) {if (!drm_mode_create_dp_colorspace_property (&aconnector->base, supported_colorspaces))drm_connector_attach_colorspace_property (&aconnector->base);
Greg Kroah-Hartman
maintainerPATCH 179/285 ARC: atomics: Add compiler barrier to atomic operations...
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pavel Kozlov <[email protected]>
commit 42f51fb24fd39cc547c086ab3d8a314cc603a91c upstream.
... to avoid unwanted gcc optimizations
SMP kernels fail to boot with commit 596ff4a09b89 ("cpumask: re-introduce constant-sized cpumask optimizations").
| | percpu: BUG: failure at mm/percpu.c:2981/pcpu_build_alloc_info()! |
The write operation performed by the SCOND instruction in the atomic inline asm code is not properly passed to the compiler. The compiler cannot correctly optimize a nested loop that runs through the cpumask in the pcpu_build_alloc_info() function.
Fix this by add a compiler barrier (memory clobber in inline asm).
Apparently atomic ops used to have memory clobber implicitly via surrounding smp_mb(). However commit b64be6836993c431e ("ARC: atomics: implement relaxed variants") removed the smp_mb() for the relaxed variants, but failed to add the explicit compiler barrier.
--- arch/arc/include/asm/atomic-llsc.h | 6 +++--- arch/arc/include/asm/atomic64-arcv2.h | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-)
arch/arc/include/asm/atomic-llsc.h +3 -3
@@ -18,7 +18,7 @@ static inline void arch_atomic_##op(int : [val] "=&r" (val) /* Early clobber to prevent reg reuse */ \: [ctr] " r" (&v->counter), /* Not " m": llock only supports reg direct addr mode */ \ [i] " ir" (i) \ - : "cc"); \ + : "cc", "memory"); \ } \ #define ATOMIC_OP_RETURN(op, asm_op) \
@@ -34,7 +34,7 @@ static inline int arch_atomic_##op##_ret : [val] "=&r" (val) \: [ctr] " r" (&v->counter), \ [i] " ir" (i) \ -: " cc"); \ +: " cc", " memory"); \ \ return val; \ }
@@ -56,7 +56,7 @@ static inline int arch_atomic_fetch_##op [orig] "=&r" (orig) \: [ctr] " r" (&v->counter), \ [i] " ir" (i) \ -: " cc"); \ +: " cc", " memory"); \ \ return orig; \ }
arch/arc/include/asm/atomic64-arcv2.h +3 -3
@@ -60,7 +60,7 @@ static inline void arch_atomic64_##op(s6" bnz 1b \n" \ : "=&r"(val) \: " r"(&v->counter), " ir"(a) \ - : "cc"); \ + : "cc", "memory"); \ } \ #define ATOMIC64_OP_RETURN(op, op1, op2) \
@@ -77,7 +77,7 @@ static inline s64 arch_atomic64_##op##_r" bnz 1b \n" \ : [val] "=&r"(val) \: " r"(&v->counter), " ir"(a) \ -: " cc"); /* memory clobber comes from smp_mb() */ \ +: " cc", " memory"); \ \ return val; \ }
@@ -99,7 +99,7 @@ static inline s64 arch_atomic64_fetch_## " bnz 1b \n" \ : "=&r"(orig), "=&r"(val) \ : "r"(&v->counter), "ir"(a) \ - : "cc"); /* memory clobber comes from smp_mb() */ \ + : "cc", "memory"); \ \return orig; \ }
Greg Kroah-Hartman
maintainerPATCH 180/285 clocksource/drivers/arm_arch_timer: Disable timer before programming CVAL
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Walter Chang <[email protected]>
commit e7d65e40ab5a5940785c5922f317602d0268caaf upstream.
Due to the fact that the use of writeq_relaxed() to program CVAL is not guaranteed to be atomic, it is necessary to disable the timer before programming CVAL.
However, if the MMIO timer is already enabled and has not yet expired, there is a possibility of unexpected behavior occurring: when the CPU enters the idle state during this period, and if the CPU's local event is earlier than the broadcast event, the following process occurs:
tick_broadcast_enter()
tick_broadcast_oneshot_control(TICK_BROADCAST_ENTER)
__tick_broadcast_oneshot_control()
___tick_broadcast_oneshot_control()
tick_broadcast_set_event()
clockevents_program_event()
set_next_event_mem()
During this process, the MMIO timer remains enabled while programming CVAL. To prevent such behavior, disable timer explicitly prior to programming CVAL.
--- drivers/clocksource/arm_arch_timer.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/clocksource/arm_arch_timer.c +7 -0
@@ -792,6 +792,13 @@ static __always_inline void set_next_eveu64 cnt; ctrl =arch_timer_reg_read (access,ARCH_TIMER_REG_CTRL , clk); + +/* Timer must be disabled before programming CVAL */ +if (ctrl &ARCH_TIMER_CTRL_ENABLE ) { + ctrl &= ~ARCH_TIMER_CTRL_ENABLE ; +arch_timer_reg_write (access,ARCH_TIMER_REG_CTRL , ctrl, clk); + } + ctrl |=ARCH_TIMER_CTRL_ENABLE ; ctrl &= ~ARCH_TIMER_CTRL_IT_MASK ;
Greg Kroah-Hartman
maintainerPATCH 181/285 dmaengine: sh: rz-dmac: Fix destination and source data size setting
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hien Huynh <[email protected]>
commit c6ec8c83a29fb3aec3efa6fabbf5344498f57c7f upstream.
Before setting DDS and SDS values, we need to clear its value first otherwise, we get incorrect results when we change/update the DMA bus width several times due to the 'OR' expression.
--- drivers/dma/sh/rz-dmac.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
drivers/dma/sh/rz-dmac.c +7 -4
@@ -9,6 +9,7 @@* Copyright 2012 Javier Martin, Vista Silicon <[email protected]> */ +#include <linux/bitfield.h> #include <linux/dma-mapping.h> #include <linux/dmaengine.h> #include <linux/interrupt.h>
@@ -145,8 +146,8 @@ struct rz_dmac {#define CHCFG_REQD BIT(3)#define CHCFG_SEL (bits) ((bits) & 0x07)#define CHCFG_MEM_COPY (0x80400008) -#define CHCFG_FILL_DDS (a) (((a) << 16) & GENMASK(19, 16)) -#define CHCFG_FILL_SDS (a) (((a) << 12) & GENMASK(15, 12)) +#define CHCFG_FILL_DDS_MASK GENMASK(19, 16) +#define CHCFG_FILL_SDS_MASK GENMASK(15, 12)#define CHCFG_FILL_TM (a) (((a) & BIT(5)) << 22)#define CHCFG_FILL_AM (a) (((a) & GENMASK(4, 2)) << 6)#define CHCFG_FILL_LVL (a) (((a) & BIT(1)) << 5)
@@ -607,13 +608,15 @@ static int rz_dmac_config(struct dma_chaif (val ==CHCFG_DS_INVALID )return -EINVAL ; - channel->chcfg |=CHCFG_FILL_DDS (val); + channel->chcfg &= ~CHCFG_FILL_DDS_MASK ; + channel->chcfg |=FIELD_PREP (CHCFG_FILL_DDS_MASK , val); val =rz_dmac_ds_to_val_mapping (config->src_addr_width);if (val ==CHCFG_DS_INVALID )return -EINVAL ; - channel->chcfg |=CHCFG_FILL_SDS (val); + channel->chcfg &= ~CHCFG_FILL_SDS_MASK ; + channel->chcfg |=FIELD_PREP (CHCFG_FILL_SDS_MASK , val);return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 182/285 misc: fastrpc: Fix remote heap allocation request
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ekansh Gupta <[email protected]>
commit ada6c2d99aedd1eac2f633d03c652e070bc2ea74 upstream.
Remote heap is used by DSP audioPD on need basis. This memory is allocated from reserved CMA memory region and is then shared with audioPD to use it for it's functionality.
Current implementation of remote heap is not allocating the memory from CMA region, instead it is allocating the memory from SMMU context bank. The arguments passed to scm call for the reassignment of ownership is also not correct. Added changes to allocate CMA memory and have a proper ownership reassignment.
--- drivers/misc/fastrpc.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
drivers/misc/fastrpc.c +7 -7
@@ -1871,7 +1871,11 @@ static int fastrpc_req_mmap(struct fastrreturn -EINVAL ; } - err =fastrpc_buf_alloc (fl, fl->sctx->dev, req.size, &buf); +if (req.flags ==ADSP_MMAP_REMOTE_HEAP_ADDR ) + err =fastrpc_remote_heap_alloc (fl, dev, req.size, &buf); +else + err =fastrpc_buf_alloc (fl, dev, req.size, &buf); +if (err) {dev_err (dev,"failed to allocate buffer\n" );return err;
@@ -1910,12 +1914,8 @@ static int fastrpc_req_mmap(struct fastr/* Add memory to static PD pool, protection thru hypervisor */ if (req.flags ==ADSP_MMAP_REMOTE_HEAP_ADDR && fl->cctx->vmcount) { -struct qcom_scm_vmperm perm; - - perm.vmid =QCOM_SCM_VMID_HLOS ; - perm.perm =QCOM_SCM_PERM_RWX ; - err =qcom_scm_assign_mem (buf->phys, buf->size, - &fl->cctx->perms, &perm,1 ); + err =qcom_scm_assign_mem (buf->phys, (u64 )buf->size, + &fl->cctx->perms, fl->cctx->vmperms, fl->cctx->vmcount);if (err) {dev_err (fl->sctx->dev,"Failed to assign memory phys 0x%llx size 0x%llx err %d" , buf->phys, buf->size, err);
Greg Kroah-Hartman
maintainerPATCH 183/285 misc: fastrpc: Fix incorrect DMA mapping unmap request
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ekansh Gupta <[email protected]>
commit a2cb9cd6a3949a3804ad9fd7da234892ce6719ec upstream.
Scatterlist table is obtained during map create request and the same table is used for DMA mapping unmap. In case there is any failure while getting the sg_table, ERR_PTR is returned instead of sg_table.
When the map is getting freed, there is only a non-NULL check of sg_table which will also be true in case failure was returned instead of sg_table. This would result in improper unmap request. Add proper check before setting map table to avoid bad unmap request.
--- drivers/misc/fastrpc.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/misc/fastrpc.c +5 -3
@@ -756,6 +756,7 @@ static int fastrpc_map_create(struct fas {struct fastrpc_session_ctx *sess = fl->sctx;struct fastrpc_map *map =NULL ; +struct sg_table *table;int err =0 ;if (!fastrpc_map_lookup (fl, fd, ppmap, true))
@@ -783,11 +784,12 @@ static int fastrpc_map_create(struct fas goto attach_err; } - map->table =dma_buf_map_attachment_unlocked (map->attach,DMA_BIDIRECTIONAL ); -if (IS_ERR (map->table)) { - err =PTR_ERR (map->table); + table =dma_buf_map_attachment_unlocked (map->attach,DMA_BIDIRECTIONAL ); +if (IS_ERR (table)) { + err =PTR_ERR (table); goto map_err; } + map->table = table;if (attr &FASTRPC_ATTR_SECUREMAP ) { map->phys =sg_phys (map->table->sgl);
Greg Kroah-Hartman
maintainerPATCH 184/285 jbd2: fix checkpoint cleanup performance regression
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhang Yi <[email protected]>
commit 373ac521799d9e97061515aca6ec6621789036bb upstream.
journal_clean_one_cp_list() has been merged into journal_shrink_one_cp_list(), but do chekpoint buffer cleanup from the committing process is just a best effort, it should stop scan once it meet a busy buffer, or else it will cause a lot of invalid buffer scan and checks. We catch a performance regression when doing fs_mark tests below.
Test cmd:
./fs_mark -d scratch -s 1024 -n 10000 -t 1 -D 100 -N 100
Before merging checkpoint buffer cleanup:
FSUse% Count Size Files/sec App Overhead
95 10000 1024 8304.9 49033After merging checkpoint buffer cleanup:
FSUse% Count Size Files/sec App Overhead
95 10000 1024 7649.0 50012
FSUse% Count Size Files/sec App Overhead
95 10000 1024 2107.1 50871After merging checkpoint buffer cleanup, the total loop count in journal_shrink_one_cp_list() could be up to 6,261,600+ (50,000+ ~ 100,000+ in general), most of them are invalid. This patch fix it through passing 'shrink_type' into journal_shrink_one_cp_list() and add a new 'SHRINK_BUSY_STOP' to indicate it should stop once meet a busy buffer. After fix, the loop count descending back to 10,000+.
After this fix:
FSUse% Count Size Files/sec App Overhead
95 10000 1024 8558.4 49109--- fs/jbd2/checkpoint.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-)
fs/jbd2/checkpoint.c +14 -6
@@ -349,6 +349,8 @@ int jbd2_cleanup_journal_tail(journal_t/* Checkpoint list management */ +enum shrink_type {SHRINK_DESTROY ,SHRINK_BUSY_STOP ,SHRINK_BUSY_SKIP }; +/* * journal_shrink_one_cp_list *
@@ -360,7 +362,8 @@ int jbd2_cleanup_journal_tail(journal_t* Called with j_list_lock held. */ static unsigned long journal_shrink_one_cp_list (struct journal_head *jh, -bool destroy,bool *released) +enum shrink_type type, +bool *released) {struct journal_head *last_jh;struct journal_head *next_jh = jh;
@@ -376,12 +379,15 @@ static unsigned long journal_shrink_one_ jh = next_jh; next_jh = jh->b_cpnext; -if (destroy) { +if (type ==SHRINK_DESTROY ) { ret =__jbd2_journal_remove_checkpoint (jh); }else { ret =jbd2_journal_try_remove_checkpoint (jh); -if (ret <0 ) -continue ; +if (ret <0 ) { +if (type ==SHRINK_BUSY_SKIP ) +continue ; +break ; + } } nr_freed++;
@@ -445,7 +451,7 @@ again: tid = transaction->t_tid; freed =journal_shrink_one_cp_list (transaction->t_checkpoint_list, - false, &released); +SHRINK_BUSY_SKIP , &released); nr_freed += freed; (*nr_to_scan) -=min (*nr_to_scan, freed);if (*nr_to_scan ==0 )
@@ -485,19 +491,21 @@ out:void __jbd2_journal_clean_checkpoint_list (journal_t *journal,bool destroy) {transaction_t *transaction, *last_transaction, *next_transaction; +enum shrink_type type;bool released; transaction = journal->j_checkpoint_transactions;if (!transaction)return ; + type = destroy ?SHRINK_DESTROY :SHRINK_BUSY_STOP ; last_transaction = transaction->t_cpprev; next_transaction = transaction; do { transaction = next_transaction; next_transaction = transaction->t_cpnext; journal_shrink_one_cp_list(transaction->t_checkpoint_list, - destroy, &released); + type, &released); /* * This function only frees up some memory if possible so we * dont have an obligation to finish processing. Bail out if
Greg Kroah-Hartman
maintainerPATCH 185/285 jbd2: check jh->b_transaction before removing it from checkpoint
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhihao Cheng <[email protected]>
commit 590a809ff743e7bd890ba5fb36bc38e20a36de53 upstream.
Following process will corrupt ext4 image:
Step 1:jbd2_journal_commit_transaction
__jbd2_journal_insert_checkpoint(jh, commit_transaction) // Put jh into trans1->t_checkpoint_list journal->j_checkpoint_transactions = commit_transaction // Put trans1 into journal->j_checkpoint_transactions
Step 2:do_get_write_access
test_clear_buffer_dirty(bh) // clear buffer dirty,set jbd dirty __jbd2_journal_file_buffer(jh, transaction) // jh belongs to trans2
Step 3:drop_cache
journal_shrink_one_cp_list
jbd2_journal_try_remove_checkpoint
if (!trylock_buffer(bh)) // lock bh, true
if (buffer_dirty(bh)) // buffer is not dirty
__jbd2_journal_remove_checkpoint(jh)
// remove jh from trans1->t_checkpoint_list
Step 4:jbd2_log_do_checkpoint
trans1 = journal->j_checkpoint_transactions // jh is not in trans1->t_checkpoint_list jbd2_cleanup_journal_tail(journal) // trans1 is done
Step 5: Power cut, trans2 is not committed, jh is lost in next mounting.
Fix it by checking 'jh->b_transaction' before remove it from checkpoint.
--- fs/jbd2/checkpoint.c | 2 ++ 1 file changed, 2 insertions(+)
fs/jbd2/checkpoint.c +2 -0
@@ -639,6 +639,8 @@ int jbd2_journal_try_remove_checkpoint(s {struct buffer_head *bh =jh2bh (jh); +if (jh->b_transaction) +return -EBUSY ;if (!trylock_buffer (bh))return -EBUSY ;if (buffer_dirty (bh)) {
Greg Kroah-Hartman
maintainerPATCH 186/285 jbd2: correct the end of the journal recovery scan range
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhang Yi <[email protected]>
commit 2dfba3bb40ad8536b9fa802364f2d40da31aa88e upstream.
We got a filesystem inconsistency issue below while running generic/475 I/O failure pressure test with fast_commit feature enabled.
Symlink /p3/d3/d1c/d6c/dd6/dce/l101 (inode #132605) is invalid.
If fast_commit feature is enabled, a special fast_commit journal area is appended to the end of the normal journal area. The journal->j_last point to the first unused block behind the normal journal area instead of the whole log area, and the journal->j_fc_last point to the first unused block behind the fast_commit journal area. While doing journal recovery, do_one_pass(PASS_SCAN) should first scan the normal journal area and turn around to the first block once it meet journal->j_last, but the wrap() macro misuse the journal->j_fc_last, so the recovering could not read the next magic block (commit block perhaps) and would end early mistakenly and missing tN and every transaction after it in the following example. Finally, it could lead to filesystem inconsistency.
| normal journal area | fast commit area |
+-------------------------------------------------+------------------+
| tN(rere) | tN+1 |~| tN-x |...| tN-1 | tN(front) | .... |
+-------------------------------------------------+------------------+
/ / /
start journal->j_last journal->j_fc_lastThis patch fix it by use the correct ending journal->j_last.
--- fs/jbd2/recovery.c | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-)
fs/jbd2/recovery.c +3 -9
@@ -230,12 +230,8 @@ static int count_tags(journal_t *journal/* Make sure we wrap around the log correctly! */ #define wrap (journal, var) \ do { \ - unsigned long _wrap_last = \ - jbd2_has_feature_fast_commit(journal) ? \ - (journal)->j_fc_last : (journal)->j_last; \ - \ - if (var >= _wrap_last) \ - var -= (_wrap_last - (journal)->j_first); \ + if (var >= (journal)->j_last) \ + var -= ((journal)->j_last - (journal)->j_first); \ } while (0) static int fc_do_one_pass(journal_t *journal,
@@ -524,9 +520,7 @@ static int do_one_pass(journal_t *journabreak ;jbd2_debug (2 ,"Scanning for sequence ID %u at %lu/%lu\n" , - next_commit_ID, next_log_block, -jbd2_has_feature_fast_commit (journal) ? - journal->j_fc_last : journal->j_last); + next_commit_ID, next_log_block, journal->j_last);/* Skip over each chunk of the transaction looking * either the next descriptor block or the final commit
Greg Kroah-Hartman
maintainerPATCH 187/285 ext4: fix slab-use-after-free in ext4_es_insert_extent()
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baokun Li <[email protected]>
commit 768d612f79822d30a1e7d132a4d4b05337ce42ec upstream.
Yikebaer reported an issue:
==================================================================
BUG: KASAN: slab-use-after-free in ext4_es_insert_extent+0xc68/0xcb0 fs/ext4/extents_status.c:894 Read of size 4 at addr ffff888112ecc1a4 by task syz-executor/8438 CPU: 1 PID: 8438 Comm: syz-executor Not tainted 6.5.0-rc5 #1 Call Trace: [...] kasan_report+0xba/0xf0 mm/kasan/report.c:588 ext4_es_insert_extent+0xc68/0xcb0 fs/ext4/extents_status.c:894 ext4_map_blocks+0x92a/0x16f0 fs/ext4/inode.c:680 ext4_alloc_file_blocks.isra.0+0x2df/0xb70 fs/ext4/extents.c:4462 ext4_zero_range fs/ext4/extents.c:4622 [inline] ext4_fallocate+0x251c/0x3ce0 fs/ext4/extents.c:4721 [...] Allocated by task 8438: [...] kmem_cache_zalloc include/linux/slab.h:693 [inline] __es_alloc_extent fs/ext4/extents_status.c:469 [inline] ext4_es_insert_extent+0x672/0xcb0 fs/ext4/extents_status.c:873 ext4_map_blocks+0x92a/0x16f0 fs/ext4/inode.c:680 ext4_alloc_file_blocks.isra.0+0x2df/0xb70 fs/ext4/extents.c:4462 ext4_zero_range fs/ext4/extents.c:4622 [inline] ext4_fallocate+0x251c/0x3ce0 fs/ext4/extents.c:4721 [...] Freed by task 8438: [...] kmem_cache_free+0xec/0x490 mm/slub.c:3823 ext4_es_try_to_merge_right fs/ext4/extents_status.c:593 [inline] __es_insert_extent+0x9f4/0x1440 fs/ext4/extents_status.c:802 ext4_es_insert_extent+0x2ca/0xcb0 fs/ext4/extents_status.c:882 ext4_map_blocks+0x92a/0x16f0 fs/ext4/inode.c:680 ext4_alloc_file_blocks.isra.0+0x2df/0xb70 fs/ext4/extents.c:4462 ext4_zero_range fs/ext4/extents.c:4622 [inline] ext4_fallocate+0x251c/0x3ce0 fs/ext4/extents.c:4721 [...] ==================================================================
The flow of issue triggering is as follows:
1. remove es
raw es es removed es1
|-------------------| -> |----|.......|------|
2. insert es
es insert es1 merge with es es1 merge with es and free es1
|----|.......|------| -> |------------|------| -> |-------------------|
es merges with newes, then merges with es1, frees es1, then determines if es1->es_len is 0 and triggers a UAF.
The code flow is as follows:ext4_es_insert_extent
es1 = __es_alloc_extent(true);
es2 = __es_alloc_extent(true);
__es_remove_extent(inode, lblk, end, NULL, es1)
__es_insert_extent(inode, &newes, es1) ---> insert es1 to es tree
__es_insert_extent(inode, &newes, es2)
ext4_es_try_to_merge_right
ext4_es_free_extent(inode, es1) ---> es1 is freed
if (es1 && !es1->es_len)
// Trigger UAF by determining if es1 is used.We determine whether es1 or es2 is used immediately after calling __es_remove_extent() or __es_insert_extent() to avoid triggering a UAF if es1 or es2 is freed.
--- fs/ext4/extents_status.c | 44 +++++++++++++++++++++++++++------------- 1 file changed, 30 insertions(+), 14 deletions(-)
fs/ext4/extents_status.c +30 -14
@@ -878,23 +878,29 @@ void ext4_es_insert_extent(struct inode *inode, ext4_lblk_t lblk, err1 =__es_remove_extent (inode, lblk, end,NULL , es1);if (err1 !=0 ) goto error; +/* Free preallocated extent if it didn't get used. */ +if (es1) { +if (!es1->es_len) +__es_free_extent (es1); + es1 =NULL ; + } err2 =__es_insert_extent (inode, &newes, es2);if (err2 == -ENOMEM && !ext4_es_must_keep (&newes)) err2 =0 ;if (err2 !=0 ) goto error; +/* Free preallocated extent if it didn't get used. */ +if (es2) { +if (!es2->es_len) +__es_free_extent (es2); + es2 =NULL ; + }if (sbi->s_cluster_ratio >1 &&test_opt (inode->i_sb,DELALLOC ) && (status &EXTENT_STATUS_WRITTEN || status &EXTENT_STATUS_UNWRITTEN ))__revise_pending (inode, lblk, len); - -/* es is pre-allocated but not used, free it. */ -if (es1 && !es1->es_len) -__es_free_extent (es1); -if (es2 && !es2->es_len) -__es_free_extent (es2); error:write_unlock (&EXT4_I (inode)->i_es_lock);if (err1 || err2)
@@ -1491,8 +1497,12 @@ void ext4_es_remove_extent(struct inode *inode, ext4_lblk_t lblk,*/ write_lock (&EXT4_I (inode)->i_es_lock); err =__es_remove_extent (inode, lblk, end, &reserved, es); -if (es && !es->es_len) -__es_free_extent (es); +/* Free preallocated extent if it didn't get used. */ +if (es) { +if (!es->es_len) +__es_free_extent (es); + es =NULL ; + }write_unlock (&EXT4_I (inode)->i_es_lock);if (err) goto retry;
@@ -2047,19 +2057,25 @@ void ext4_es_insert_delayed_block(struct inode *inode, ext4_lblk_t lblk, err1 =__es_remove_extent (inode, lblk, lblk,NULL , es1);if (err1 !=0 ) goto error; +/* Free preallocated extent if it didn't get used. */ +if (es1) { +if (!es1->es_len) +__es_free_extent (es1); + es1 =NULL ; + } err2 =__es_insert_extent (inode, &newes, es2);if (err2 !=0 ) goto error; +/* Free preallocated extent if it didn't get used. */ +if (es2) { +if (!es2->es_len) +__es_free_extent (es2); + es2 =NULL ; + }if (allocated)__insert_pending (inode, lblk); - -/* es is pre-allocated but not used, free it. */ -if (es1 && !es1->es_len) -__es_free_extent (es1); -if (es2 && !es2->es_len) -__es_free_extent (es2); error:write_unlock (&EXT4_I (inode)->i_es_lock);if (err1 || err2)
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 188/285 ext4: add correct group descriptors and reserved GDT blocks to system zone
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wang Jianjian <[email protected]>
commit 68228da51c9a436872a4ef4b5a7692e29f7e5bc7 upstream.
When setup_system_zone, flex_bg is not initialized so it is always 1. Use a new helper function, ext4_num_base_meta_blocks() which does not depend on sbi->s_log_groups_per_flex being initialized.
[ Squashed two patches in the Link URL's below together into a single
commit, which is simpler to review/understand. Also fix checkpatch warnings. --TYT ]
--- fs/ext4/balloc.c | 15 +++++++++++---- fs/ext4/block_validity.c | 8 ++++---- fs/ext4/ext4.h | 2 ++ 3 files changed, 17 insertions(+), 8 deletions(-)
fs/ext4/balloc.c +11 -4
@@ -913,11 +913,11 @@ unsigned long ext4_bg_num_gdb(struct sup }/* -* This function returns the number of file system metadata clusters at +* This function returns the number of file system metadata blocks at * the beginning of a block group, including the reserved gdt blocks. */ -static unsigned ext4_num_base_meta_clusters (struct super_block *sb, -ext4_group_t block_group) +unsigned int ext4_num_base_meta_blocks (struct super_block *sb, +ext4_group_t block_group) {struct ext4_sb_info *sbi =EXT4_SB (sb);unsigned num;
@@ -935,8 +935,15 @@ static unsigned ext4_num_base_meta_clust }else {/* For META_BG_BLOCK_GROUPS */ num +=ext4_bg_num_gdb_meta (sb, block_group); } -return EXT4_NUM_B2C (sbi, num); +return num; } + +static unsigned int ext4_num_base_meta_clusters (struct super_block *sb, +ext4_group_t block_group) +{ +return EXT4_NUM_B2C (EXT4_SB (sb),ext4_num_base_meta_blocks (sb, block_group)); +} +/** * ext4_inode_to_goal_block - return a hint for block allocation * @inode: inode for block allocation
fs/ext4/block_validity.c +4 -4
@@ -215,7 +215,6 @@ int ext4_setup_system_zone(struct super_struct ext4_system_blocks *system_blks;struct ext4_group_desc *gdp;ext4_group_t i; -int flex_size =ext4_flex_bg_size (sbi);int ret; system_blks =kzalloc (sizeof (*system_blks),GFP_KERNEL );
@@ -223,12 +222,13 @@ int ext4_setup_system_zone(struct super_return -ENOMEM ;for (i=0 ; i < ngroups; i++) { +unsigned int meta_blks =ext4_num_base_meta_blocks (sb, i); +cond_resched (); -if (ext4_bg_has_super (sb, i) && - ((i <5 ) || ((i % flex_size) ==0 ))) { +if (meta_blks !=0 ) { ret =add_system_zone (system_blks,ext4_group_first_block_no (sb, i), -ext4_bg_num_gdb (sb, i) +1 ,0 ); + meta_blks,0 );if (ret) goto err; }
fs/ext4/ext4.h +2 -0
@@ -3084,6 +3084,8 @@ extern const char *ext4_decode_error(strextern void ext4_mark_group_bitmap_corrupted (struct super_block *sb,ext4_group_t block_group,unsigned int flags); +extern unsigned int ext4_num_base_meta_blocks (struct super_block *sb, +ext4_group_t block_group); extern __printf(7, 8) void __ext4_error(struct super_block *, const char *, unsigned int, bool,
Greg Kroah-Hartman
maintainerPATCH 189/285 ext4: fix memory leaks in ext4_fname_{setup_filename,prepare_lookup}
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luís Henriques <[email protected]>
commit 7ca4b085f430f3774c3838b3da569ceccd6a0177 upstream.
If the filename casefolding fails, we'll be leaking memory from the fscrypt_name struct, namely from the 'crypto_buf.name' member.
Make sure we free it in the error path on both ext4_fname_setup_filename() and ext4_fname_prepare_lookup() functions.
--- fs/ext4/crypto.c | 4 ++++ 1 file changed, 4 insertions(+)
fs/ext4/crypto.c +4 -0
@@ -33,6 +33,8 @@ int ext4_fname_setup_filename(struct ino#if IS_ENABLED (CONFIG_UNICODE ) err =ext4_fname_setup_ci_filename (dir, iname, fname); +if (err) +ext4_fname_free_filename (fname);#endif return err; }
@@ -51,6 +53,8 @@ int ext4_fname_prepare_lookup(struct ino#if IS_ENABLED (CONFIG_UNICODE ) err =ext4_fname_setup_ci_filename (dir, &dentry->d_name, fname); +if (err) +ext4_fname_free_filename (fname);#endif return err; }
Greg Kroah-Hartman
maintainerPATCH 190/285 ext4: drop dio overwrite only flag and associated warning
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Brian Foster <[email protected]>
commit 194505b55dd7899da114a4d47825204eefc0fff5 upstream.
The commit referenced below opened up concurrent unaligned dio under shared locking for pure overwrites. In doing so, it enabled use of the IOMAP_DIO_OVERWRITE_ONLY flag and added a warning on unexpected -EAGAIN returns as an extra precaution, since ext4 does not retry writes in such cases. The flag itself is advisory in this case since ext4 checks for unaligned I/Os and uses appropriate locking up front, rather than on a retry in response to -EAGAIN.
As it turns out, the warning check is susceptible to false positives because there are scenarios where -EAGAIN can be expected from lower layers without necessarily having IOCB_NOWAIT set on the iocb. For example, one instance of the warning has been seen where io_uring sets IOCB_HIPRI, which in turn results in REQ_POLLED|REQ_NOWAIT on the bio. This results in -EAGAIN if the block layer is unable to allocate a request, etc. [Note that there is an outstanding patch to untangle REQ_POLLED and REQ_NOWAIT such that the latter relies on IOCB_NOWAIT, which would also address this instance of the warning.]
Another instance of the warning has been reproduced by syzbot. A dio write is interrupted down in __get_user_pages_locked() waiting on the mm lock and returns -EAGAIN up the stack. If the iomap dio iteration layer has made no progress on the write to this point, -EAGAIN returns up to the filesystem and triggers the warning.
This use of the overwrite flag in ext4 is precautionary and half-baked. I.e., ext4 doesn't actually implement overwrite checking in the iomap callbacks when the flag is set, so the only extra verification it provides are i_size checks in the generic iomap dio layer. Combined with the tendency for false positives, the added verification is not worth the extra trouble. Remove the flag, associated warning, and update the comments to document when concurrent unaligned dio writes are allowed and why said flag is not used.
--- fs/ext4/file.c | 25 ++++++++++--------------- 1 file changed, 10 insertions(+), 15 deletions(-)
fs/ext4/file.c +10 -15
@@ -476,6 +476,11 @@ static ssize_t ext4_dio_write_checks(struct kiocb *iocb, struct iov_iter *from,* required to change security info in file_modified(), for extending * I/O, any form of non-overwrite I/O, and unaligned I/O to unwritten * extents (as partial block zeroing may be required). +* +* Note that unaligned writes are allowed under shared lock so long as +* they are pure overwrites. Otherwise, concurrent unaligned writes risk +* data corruption due to partial block zeroing in the dio layer, and so +* the I/O must occur exclusively. */ if (*ilock_shared && ((!IS_NOSEC(inode) || *extend || !overwrite ||
@@ -492,21 +497,12 @@ static ssize_t ext4_dio_write_checks(struct kiocb *iocb, struct iov_iter *from,/* * Now that locking is settled, determine dio flags and exclusivity -* requirements. Unaligned writes are allowed under shared lock so long -* as they are pure overwrites. Set the iomap overwrite only flag as an -* added precaution in this case. Even though this is unnecessary, we -* can detect and warn on unexpected -EAGAIN if an unsafe unaligned -* write is ever submitted. -* -* Otherwise, concurrent unaligned writes risk data corruption due to -* partial block zeroing in the dio layer, and so the I/O must occur -* exclusively. The inode lock is already held exclusive if the write is -* non-overwrite or extending, so drain all outstanding dio and set the -* force wait dio flag. +* requirements. We don't use DIO_OVERWRITE_ONLY because we enforce +* behavior already. The inode lock is already held exclusive if the +* write is non-overwrite or extending, so drain all outstanding dio and +* set the force wait dio flag. */ -if (*ilock_shared && unaligned_io) { - *dio_flags =IOMAP_DIO_OVERWRITE_ONLY ; - }else if (!*ilock_shared && (unaligned_io || *extend)) { +if (!*ilock_shared && (unaligned_io || *extend)) {if (iocb->ki_flags &IOCB_NOWAIT ) { ret = -EAGAIN ; goto out;
@@ -608,7 +604,6 @@ static ssize_t ext4_dio_write_iter(struct kiocb *iocb, struct iov_iter *from) iomap_ops = &ext4_iomap_overwrite_ops; ret =iomap_dio_rw (iocb, from, iomap_ops, &ext4_dio_write_ops, dio_flags,NULL ,0 ); -WARN_ON_ONCE (ret == -EAGAIN && !(iocb->ki_flags &IOCB_NOWAIT ));if (ret == -ENOTBLK ) ret =0 ;
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 191/285 f2fs: get out of a repeat loop when getting a locked data page
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jaegeuk Kim <[email protected]>
commit d2d9bb3b6d2fbccb5b33d3a85a2830971625a4ea upstream.
https://bugzilla.kernel.org/show_bug.cgi?id=216050
Somehow we're getting a page which has a different mapping. Let's avoid the infinite loop.
--- fs/f2fs/data.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-)
fs/f2fs/data.c +2 -6
@@ -1389,18 +1389,14 @@ struct page *f2fs_get_lock_data_page(str {struct address_space *mapping = inode->i_mapping;struct page *page; -repeat: + page =f2fs_get_read_data_page (inode, index,0 , for_write,NULL );if (IS_ERR (page))return page;/* wait for read completion */ lock_page (page); -if (unlikely (page->mapping != mapping)) { -f2fs_put_page (page,1 ); - goto repeat; - } -if (unlikely (!PageUptodate (page))) { +if (unlikely (page->mapping != mapping || !PageUptodate (page))) {f2fs_put_page (page,1 );return ERR_PTR (-EIO ); }
Greg Kroah-Hartman
maintainerPATCH 192/285 f2fs: flush inode if atomic file is aborted
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jaegeuk Kim <[email protected]>
commit a3ab55746612247ce3dcaac6de66f5ffc055b9df upstream.
Let's flush the inode being aborted atomic operation to avoid stale dirty inode during eviction in this call stack:
f2fs_mark_inode_dirty_sync+0x22/0x40 [f2fs] f2fs_abort_atomic_write+0xc4/0xf0 [f2fs] f2fs_evict_inode+0x3f/0x690 [f2fs] ? sugov_start+0x140/0x140 evict+0xc3/0x1c0 evict_inodes+0x17b/0x210 generic_shutdown_super+0x32/0x120 kill_block_super+0x21/0x50 deactivate_locked_super+0x31/0x90 cleanup_mnt+0x100/0x160 task_work_run+0x59/0x90 do_exit+0x33b/0xa50 do_group_exit+0x2d/0x80 __x64_sys_exit_group+0x14/0x20 do_syscall_64+0x3b/0x90 entry_SYSCALL_64_after_hwframe+0x63/0xcd
This triggers f2fs_bug_on() in f2fs_evict_inode:
f2fs_bug_on(sbi, is_inode_flag_set(inode, FI_DIRTY_INODE));
This fixes the syzbot report:
loop0: detected capacity change from 0 to 131072 F2FS-fs (loop0): invalid crc value
F2FS-fs (loop0): Found nat_bits in checkpoint F2FS-fs (loop0): Mounted with checkpoint version = 48b305e4
------------[ cut here ]------------ kernel BUG at fs/f2fs/inode.c:869! invalid opcode: 0000 [#1] PREEMPT SMP KASAN CPU: 0 PID: 5014 Comm: syz-executor220 Not tainted 6.4.0-syzkaller-11479-g6cd06ab12d1a #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 05/27/2023 RIP: 0010:f2fs_evict_inode+0x172d/0x1e00 fs/f2fs/inode.c:869 Code: ff df 48 c1 ea 03 80 3c 02 00 0f 85 6a 06 00 00 8b 75 40 ba 01 00 00 00 4c 89 e7 e8 6d ce 06 00 e9 aa fc ff ff e8 63 22 e2 fd <0f> 0b e8 5c 22 e2 fd 48 c7 c0 a8 3a 18 8d 48 ba 00 00 00 00 00 fc RSP: 0018:ffffc90003a6fa00 EFLAGS: 00010293 RAX: 0000000000000000 RBX: 0000000000000001 RCX: 0000000000000000 RDX: ffff8880273b8000 RSI: ffffffff83a2bd0d RDI: 0000000000000007 RBP: ffff888077db91b0 R08: 0000000000000007 R09: 0000000000000000 R10: 0000000000000001 R11: 0000000000000001 R12: ffff888029a3c000 R13: ffff888077db9660 R14: ffff888029a3c0b8 R15: ffff888077db9c50 FS: 0000000000000000(0000) GS:ffff8880b9800000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f1909bb9000 CR3: 00000000276a9000 CR4: 0000000000350ef0 Call Trace: <TASK> evict+0x2ed/0x6b0 fs/inode.c:665 dispose_list+0x117/0x1e0 fs/inode.c:698 evict_inodes+0x345/0x440 fs/inode.c:748 generic_shutdown_super+0xaf/0x480 fs/super.c:478 kill_block_super+0x64/0xb0 fs/super.c:1417 kill_f2fs_super+0x2af/0x3c0 fs/f2fs/super.c:4704 deactivate_locked_super+0x98/0x160 fs/super.c:330 deactivate_super+0xb1/0xd0 fs/super.c:361 cleanup_mnt+0x2ae/0x3d0 fs/namespace.c:1254 task_work_run+0x16f/0x270 kernel/task_work.c:179 exit_task_work include/linux/task_work.h:38 [inline] do_exit+0xa9a/0x29a0 kernel/exit.c:874 do_group_exit+0xd4/0x2a0 kernel/exit.c:1024 __do_sys_exit_group kernel/exit.c:1035 [inline] __se_sys_exit_group kernel/exit.c:1033 [inline] __x64_sys_exit_group+0x3e/0x50 kernel/exit.c:1033 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x39/0xb0 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x63/0xcd RIP: 0033:0x7f309be71a09 Code: Unable to access opcode bytes at 0x7f309be719df. RSP: 002b:00007fff171df518 EFLAGS: 00000246 ORIG_RAX: 00000000000000e7 RAX: ffffffffffffffda RBX: 00007f309bef7330 RCX: 00007f309be71a09 RDX: 000000000000003c RSI: 00000000000000e7 RDI: 0000000000000001 RBP: 0000000000000001 R08: ffffffffffffffc0 R09: 00007f309bef1e40 R10: 0000000000010600 R11: 0000000000000246 R12: 00007f309bef7330 R13: 0000000000000001 R14: 0000000000000000 R15: 0000000000000001 </TASK> Modules linked in: ---[ end trace 0000000000000000 ]--- RIP: 0010:f2fs_evict_inode+0x172d/0x1e00 fs/f2fs/inode.c:869 Code: ff df 48 c1 ea 03 80 3c 02 00 0f 85 6a 06 00 00 8b 75 40 ba 01 00 00 00 4c 89 e7 e8 6d ce 06 00 e9 aa fc ff ff e8 63 22 e2 fd <0f> 0b e8 5c 22 e2 fd 48 c7 c0 a8 3a 18 8d 48 ba 00 00 00 00 00 fc RSP: 0018:ffffc90003a6fa00 EFLAGS: 00010293 RAX: 0000000000000000 RBX: 0000000000000001 RCX: 0000000000000000 RDX: ffff8880273b8000 RSI: ffffffff83a2bd0d RDI: 0000000000000007 RBP: ffff888077db91b0 R08: 0000000000000007 R09: 0000000000000000 R10: 0000000000000001 R11: 0000000000000001 R12: ffff888029a3c000 R13: ffff888077db9660 R14: ffff888029a3c0b8 R15: ffff888077db9c50 FS: 0000000000000000(0000) GS:ffff8880b9800000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 00007f1909bb9000 CR3: 00000000276a9000 CR4: 0000000000350ef0
--- fs/f2fs/segment.c | 2 ++ 1 file changed, 2 insertions(+)
fs/f2fs/segment.c +2 -0
@@ -205,6 +205,8 @@ void f2fs_abort_atomic_write(struct inodf2fs_i_size_write (inode, fi->original_i_size); fi->original_i_size =0 ; } +/* avoid stale dirty inode during eviction */ +sync_inode_metadata (inode,0 ); } static int __replace_atomic_write_block(struct inode *inode, pgoff_t index,
Greg Kroah-Hartman
maintainerPATCH 193/285 f2fs: avoid false alarm of circular locking
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jaegeuk Kim <[email protected]>
commit 5c13e2388bf3426fd69a89eb46e50469e9624e56 upstream.
======================================================
WARNING: possible circular locking dependency detected 6.5.0-rc5-syzkaller-00353-gae545c3283dc #0 Not tainted
------------------------------------------------------
syz-executor273/5027 is trying to acquire lock:ffff888077fe1fb0 (&fi->i_sem){+.+.}-{3:3}, at: f2fs_down_write fs/f2fs/f2fs.h:2133 [inline] ffff888077fe1fb0 (&fi->i_sem){+.+.}-{3:3}, at: f2fs_add_inline_entry+0x300/0x6f0 fs/f2fs/inline.c:644
but task is already holding lock:ffff888077fe07c8 (&fi->i_xattr_sem){.+.+}-{3:3}, at: f2fs_down_read fs/f2fs/f2fs.h:2108 [inline] ffff888077fe07c8 (&fi->i_xattr_sem){.+.+}-{3:3}, at: f2fs_add_dentry+0x92/0x230 fs/f2fs/dir.c:783
which lock already depends on the new lock.
the existing dependency chain (in reverse order) is:
-> #1 (&fi->i_xattr_sem){.+.+}-{3:3}:
down_read+0x9c/0x470 kernel/locking/rwsem.c:1520
f2fs_down_read fs/f2fs/f2fs.h:2108 [inline]
f2fs_getxattr+0xb1e/0x12c0 fs/f2fs/xattr.c:532
__f2fs_get_acl+0x5a/0x900 fs/f2fs/acl.c:179
f2fs_acl_create fs/f2fs/acl.c:377 [inline]
f2fs_init_acl+0x15c/0xb30 fs/f2fs/acl.c:420
f2fs_init_inode_metadata+0x159/0x1290 fs/f2fs/dir.c:558
f2fs_add_regular_entry+0x79e/0xb90 fs/f2fs/dir.c:740
f2fs_add_dentry+0x1de/0x230 fs/f2fs/dir.c:788
f2fs_do_add_link+0x190/0x280 fs/f2fs/dir.c:827
f2fs_add_link fs/f2fs/f2fs.h:3554 [inline]
f2fs_mkdir+0x377/0x620 fs/f2fs/namei.c:781
vfs_mkdir+0x532/0x7e0 fs/namei.c:4117
do_mkdirat+0x2a9/0x330 fs/namei.c:4140
__do_sys_mkdir fs/namei.c:4160 [inline]
__se_sys_mkdir fs/namei.c:4158 [inline]
__x64_sys_mkdir+0xf2/0x140 fs/namei.c:4158
do_syscall_x64 arch/x86/entry/common.c:50 [inline]
do_syscall_64+0x38/0xb0 arch/x86/entry/common.c:80
entry_SYSCALL_64_after_hwframe+0x63/0xcd-> #0 (&fi->i_sem){+.+.}-{3:3}:
check_prev_add kernel/locking/lockdep.c:3142 [inline]
check_prevs_add kernel/locking/lockdep.c:3261 [inline]
validate_chain kernel/locking/lockdep.c:3876 [inline]
__lock_acquire+0x2e3d/0x5de0 kernel/locking/lockdep.c:5144
lock_acquire kernel/locking/lockdep.c:5761 [inline]
lock_acquire+0x1ae/0x510 kernel/locking/lockdep.c:5726
down_write+0x93/0x200 kernel/locking/rwsem.c:1573
f2fs_down_write fs/f2fs/f2fs.h:2133 [inline]
f2fs_add_inline_entry+0x300/0x6f0 fs/f2fs/inline.c:644
f2fs_add_dentry+0xa6/0x230 fs/f2fs/dir.c:784
f2fs_do_add_link+0x190/0x280 fs/f2fs/dir.c:827
f2fs_add_link fs/f2fs/f2fs.h:3554 [inline]
f2fs_mkdir+0x377/0x620 fs/f2fs/namei.c:781
vfs_mkdir+0x532/0x7e0 fs/namei.c:4117
ovl_do_mkdir fs/overlayfs/overlayfs.h:196 [inline]
ovl_mkdir_real+0xb5/0x370 fs/overlayfs/dir.c:146
ovl_workdir_create+0x3de/0x820 fs/overlayfs/super.c:309
ovl_make_workdir fs/overlayfs/super.c:711 [inline]
ovl_get_workdir fs/overlayfs/super.c:864 [inline]
ovl_fill_super+0xdab/0x6180 fs/overlayfs/super.c:1400
vfs_get_super+0xf9/0x290 fs/super.c:1152
vfs_get_tree+0x88/0x350 fs/super.c:1519
do_new_mount fs/namespace.c:3335 [inline]
path_mount+0x1492/0x1ed0 fs/namespace.c:3662
do_mount fs/namespace.c:3675 [inline]
__do_sys_mount fs/namespace.c:3884 [inline]
__se_sys_mount fs/namespace.c:3861 [inline]
__x64_sys_mount+0x293/0x310 fs/namespace.c:3861
do_syscall_x64 arch/x86/entry/common.c:50 [inline]
do_syscall_64+0x38/0xb0 arch/x86/entry/common.c:80
entry_SYSCALL_64_after_hwframe+0x63/0xcdother info that might help us debug this:
Possible unsafe locking scenario:
CPU0 CPU1
---- ----
rlock(&fi->i_xattr_sem);
lock(&fi->i_sem);
lock(&fi->i_xattr_sem); lock(&fi->i_sem);
--- fs/f2fs/f2fs.h | 24 +++++++++++++++--------- fs/f2fs/inline.c | 3 ++- 2 files changed, 17 insertions(+), 10 deletions(-)
fs/f2fs/f2fs.h +15 -9
@@ -2122,15 +2122,6 @@ static inline int f2fs_down_read_trylockreturn down_read_trylock (&sem->internal_rwsem); } -#ifdef CONFIG_DEBUG_LOCK_ALLOC -static inline void f2fs_down_read_nested (struct f2fs_rwsem *sem,int subclass) -{ -down_read_nested (&sem->internal_rwsem, subclass); -} -#else -#define f2fs_down_read_nested (sem, subclass) f2fs_down_read(sem) -#endif -static inline void f2fs_up_read (struct f2fs_rwsem *sem) {up_read (&sem->internal_rwsem);
@@ -2141,6 +2132,21 @@ static inline void f2fs_down_write(strucdown_write (&sem->internal_rwsem); } +#ifdef CONFIG_DEBUG_LOCK_ALLOC +static inline void f2fs_down_read_nested (struct f2fs_rwsem *sem,int subclass) +{ +down_read_nested (&sem->internal_rwsem, subclass); +} + +static inline void f2fs_down_write_nested (struct f2fs_rwsem *sem,int subclass) +{ +down_write_nested (&sem->internal_rwsem, subclass); +} +#else +#define f2fs_down_read_nested (sem, subclass) f2fs_down_read(sem) +#define f2fs_down_write_nested (sem, subclass) f2fs_down_write(sem) +#endif +static inline int f2fs_down_write_trylock (struct f2fs_rwsem *sem) {return down_write_trylock (&sem->internal_rwsem);
fs/f2fs/inline.c +2 -1
@@ -641,7 +641,8 @@ int f2fs_add_inline_entry(struct inode * }if (inode) { -f2fs_down_write (&F2FS_I (inode)->i_sem); +f2fs_down_write_nested (&F2FS_I (inode)->i_sem, +SINGLE_DEPTH_NESTING ); page =f2fs_init_inode_metadata (inode, dir, fname, ipage);if (IS_ERR (page)) { err =PTR_ERR (page);
Greg Kroah-Hartman
maintainerPATCH 194/285 lib: test_scanf: Add explicit type cast to result initialization in test_number_prefix()
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nathan Chancellor <[email protected]>
commit 92382d744176f230101d54f5c017bccd62770f01 upstream.
A recent change in clang allows it to consider more expressions as compile time constants, which causes it to point out an implicit conversion in the scanf tests:
lib/test_scanf.c:661:2: warning: implicit conversion from 'int' to 'unsigned char' changes value from -168 to 88 [-Wconstant-conversion]
661 | test_number_prefix(unsigned char, "0xA7", "%2hhx%hhx", 0, 0xa7, 2, check_uchar);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
lib/test_scanf.c:609:29: note: expanded from macro 'test_number_prefix'
609 | T result[2] = {~expect[0], ~expect[1]}; \
| ~ ^~~~~~~~~~
1 warning generated.The result of the bitwise negation is the type of the operand after going through the integer promotion rules, so this truncation is expected but harmless, as the initial values in the result array get overwritten by _test() anyways. Add an explicit cast to the expected type in test_number_prefix() to silence the warning. There is no functional change, as all the tests still pass with GCC 13.1.0 and clang 18.0.0.
--- lib/test_scanf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
lib/test_scanf.c +1 -1
@@ -606,7 +606,7 @@ static void __init numbers_slice(void)#define test_number_prefix (T , str, scan_fmt, expect0, expect1, n_args, fn) \ do { \ const T expect[2] = { expect0, expect1 }; \ - T result[2] = {~expect[0], ~expect[1]}; \ + T result[2] = { (T)~expect[0], (T)~expect[1] }; \ \ _test(fn, &expect, str, scan_fmt, n_args, &result[0], &result[1]); \ } while (0)
Greg Kroah-Hartman
maintainerPATCH 195/285 hwspinlock: qcom: add missing regmap config for SFPB MMIO implementation
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Marangi <[email protected]>
commit 23316be8a9d450f33a21f1efe7d89570becbec58 upstream.
Commit 5d4753f741d8 ("hwspinlock: qcom: add support for MMIO on older SoCs") introduced and made regmap_config mandatory in the of_data struct but didn't add the regmap_config for sfpb based devices.
SFPB based devices can both use the legacy syscon way to probe or the new MMIO way and currently device that use the MMIO way are broken as they lack the definition of the now required regmap_config and always return -EINVAL (and indirectly makes fail probing everything that depends on it, smem, nandc with smem-parser...)
Fix this by correctly adding the missing regmap_config and restore function of hwspinlock on SFPB based devices with MMIO implementation.
--- drivers/hwspinlock/qcom_hwspinlock.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/hwspinlock/qcom_hwspinlock.c +9 -0
@@ -69,9 +69,18 @@ static const struct hwspinlock_ops qcom_ .unlock = qcom_hwspinlock_unlock, }; +static const struct regmap_config sfpb_mutex_config = { + .reg_bits =32 , + .reg_stride =4 , + .val_bits =32 , + .max_register =0x100 , + .fast_io = true, +}; +static const struct qcom_hwspinlock_of_data of_sfpb_mutex = { .offset =0x4 , .stride =0x4 , + .regmap_config = &sfpb_mutex_config, };static const struct regmap_config tcsr_msm8226_mutex_config = {
Greg Kroah-Hartman
maintainerPATCH 196/285 memcontrol: ensure memcg acquired by id is properly set up
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Weiner <[email protected]>
commit 6f0df8e16eb543167f2929cb756e695709a3551d upstream.
In the eviction recency check, we attempt to retrieve the memcg to which the folio belonged when it was evicted, by the memcg id stored in the shadow entry. However, there is a chance that the retrieved memcg is not the original memcg that has been killed, but a new one which happens to have the same id.
This is a somewhat unfortunate, but acceptable and rare inaccuracy in the heuristics. However, if we retrieve this new memcg between its allocation and when it is properly attached to the memcg hierarchy, we could run into the following NULL pointer exception during the memcg hierarchy traversal done in mem_cgroup_get_nr_swap_pages():
[ 155757.793456] BUG: kernel NULL pointer dereference, address: 00000000000000c0 [ 155757.807568] #PF: supervisor read access in kernel mode [ 155757.818024] #PF: error_code(0x0000) - not-present page [ 155757.828482] PGD 401f77067 P4D 401f77067 PUD 401f76067 PMD 0 [ 155757.839985] Oops: 0000 [#1] SMP [ 155757.887870] RIP: 0010:mem_cgroup_get_nr_swap_pages+0x3d/0xb0 [ 155757.899377] Code: 29 19 4a 02 48 39 f9 74 63 48 8b 97 c0 00 00 00 48 8b b7 58 02 00 00 48 2b b7 c0 01 00 00 48 39 f0 48 0f 4d c6 48 39 d1 74 42 <48> 8b b2 c0 00 00 00 48 8b ba 58 02 00 00 48 2b ba c0 01 00 00 48 [ 155757.937125] RSP: 0018:ffffc9002ecdfbc8 EFLAGS: 00010286 [ 155757.947755] RAX: 00000000003a3b1c RBX: 000007ffffffffff RCX: ffff888280183000 [ 155757.962202] RDX: 0000000000000000 RSI: 0007ffffffffffff RDI: ffff888bbc2d1000 [ 155757.976648] RBP: 0000000000000001 R08: 000000000000000b R09: ffff888ad9cedba0 [ 155757.991094] R10: ffffea0039c07900 R11: 0000000000000010 R12: ffff888b23a7b000 [ 155758.005540] R13: 0000000000000000 R14: ffff888bbc2d1000 R15: 000007ffffc71354 [ 155758.019991] FS: 00007f6234c68640(0000) GS:ffff88903f9c0000(0000) knlGS:0000000000000000 [ 155758.036356] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 155758.048023] CR2: 00000000000000c0 CR3: 0000000a83eb8004 CR4: 00000000007706e0 [ 155758.062473] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 155758.076924] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 [ 155758.091376] PKRU: 55555554 [ 155758.096957] Call Trace: [ 155758.102016] <TASK> [ 155758.106502] ? __die+0x78/0xc0 [ 155758.112793] ? page_fault_oops+0x286/0x380 [ 155758.121175] ? exc_page_fault+0x5d/0x110 [ 155758.129209] ? asm_exc_page_fault+0x22/0x30 [ 155758.137763] ? mem_cgroup_get_nr_swap_pages+0x3d/0xb0 [ 155758.148060] workingset_test_recent+0xda/0x1b0 [ 155758.157133] workingset_refault+0xca/0x1e0 [ 155758.165508] filemap_add_folio+0x4d/0x70 [ 155758.173538] page_cache_ra_unbounded+0xed/0x190 [ 155758.182919] page_cache_sync_ra+0xd6/0x1e0 [ 155758.191738] filemap_read+0x68d/0xdf0 [ 155758.199495] ? mlx5e_napi_poll+0x123/0x940 [ 155758.207981] ? __napi_schedule+0x55/0x90 [ 155758.216095] __x64_sys_pread64+0x1d6/0x2c0 [ 155758.224601] do_syscall_64+0x3d/0x80 [ 155758.232058] entry_SYSCALL_64_after_hwframe+0x46/0xb0 [ 155758.242473] RIP: 0033:0x7f62c29153b5 [ 155758.249938] Code: e8 48 89 75 f0 89 7d f8 48 89 4d e0 e8 b4 e6 f7 ff 41 89 c0 4c 8b 55 e0 48 8b 55 e8 48 8b 75 f0 8b 7d f8 b8 11 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 33 44 89 c7 48 89 45 f8 e8 e7 e6 f7 ff 48 8b [ 155758.288005] RSP: 002b:00007f6234c5ffd0 EFLAGS: 00000293 ORIG_RAX: 0000000000000011 [ 155758.303474] RAX: ffffffffffffffda RBX: 00007f628c4e70c0 RCX: 00007f62c29153b5 [ 155758.318075] RDX: 000000000003c041 RSI: 00007f61d2986000 RDI: 0000000000000076 [ 155758.332678] RBP: 00007f6234c5fff0 R08: 0000000000000000 R09: 0000000064d5230c [ 155758.347452] R10: 000000000027d450 R11: 0000000000000293 R12: 000000000003c041 [ 155758.362044] R13: 00007f61d2986000 R14: 00007f629e11b060 R15: 000000000027d450 [ 155758.376661] </TASK>
This patch fixes the issue by moving the memcg's id publication from the alloc stage to online stage, ensuring that any memcg acquired via id must be connected to the memcg tree.
--- mm/memcontrol.c | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-)
mm/memcontrol.c +17 -5
@@ -5329,7 +5329,6 @@ static struct mem_cgroup *mem_cgroup_allINIT_LIST_HEAD (&memcg->deferred_split_queue.split_queue); memcg->deferred_split_queue.split_queue_len =0 ;#endif -idr_replace (&mem_cgroup_idr, memcg, memcg->id.id);lru_gen_init_memcg (memcg);return memcg; fail:
@@ -5401,14 +5400,27 @@ static int mem_cgroup_css_online(structif (alloc_shrinker_info (memcg)) goto offline_kmem; -/* Online state pins memcg ID, memcg ID pins CSS */ -refcount_set (&memcg->id.ref,1 ); -css_get (css); -if (unlikely (mem_cgroup_is_root (memcg)))queue_delayed_work (system_unbound_wq, &stats_flush_dwork,FLUSH_TIME );lru_gen_online_memcg (memcg); + +/* Online state pins memcg ID, memcg ID pins CSS */ +refcount_set (&memcg->id.ref,1 ); +css_get (css); + +/* +* Ensure mem_cgroup_from_id() works once we're fully online. +* +* We could do this earlier and require callers to filter with +* css_tryget_online(). But right now there are no users that +* need earlier access, and the workingset code relies on the +* cgroup tree linkage (mem_cgroup_get_nr_swap_pages()). So +* publish it here at the end of onlining. This matches the +* regular ID destruction during offlining. +*/ +idr_replace (&mem_cgroup_idr, memcg, memcg->id.id); +return 0 ; offline_kmem:memcg_offline_kmem (memcg);
Greg Kroah-Hartman
maintainerPATCH 197/285 ata: ahci: Add Elkhart Lake AHCI controller
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Werner Fischer <[email protected]>
commit 2a2df98ec592667927b5c1351afa6493ea125c9f upstream.
Elkhart Lake is the successor of Apollo Lake and Gemini Lake. These CPUs and their PCHs are used in mobile and embedded environments.
With this patch I suggest that Elkhart Lake SATA controllers [1] should use the default LPM policy for mobile chipsets.
The disadvantage of missing hot-plug support with this setting should not be an issue, as those CPUs are used in embedded environments and not in servers with hot-plug backplanes.
We discovered that the Elkhart Lake SATA controllers have been missing in ahci.c after a customer reported the throttling of his SATA SSD after a short period of higher I/O. We determined the high temperature of the SSD controller in idle mode as the root cause for that.
Depending on the used SSD, we have seen up to 1.8 Watt lower system idle power usage and up to 30°C lower SSD controller temperatures in our tests, when we set med_power_with_dipm manually. I have provided a table showing seven different SATA SSDs from ATP, Intel/Solidigm and Samsung [2].
Intel lists a total of 3 SATA controller IDs (4B60, 4B62, 4B63) in [1] for those mobile PCHs.
This commit just adds 0x4b63 as I do not have test systems with 0x4b60 and 0x4b62 SATA controllers.
I have tested this patch with a system which uses 0x4b63 as SATA controller.
[1] https://sata-io.org/product/8803
[2] https://www.thomas-krenn.com/en/wiki/SATA_Link_Power_Management#Example_LES_v4
--- drivers/ata/ahci.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/ata/ahci.c +2 -0
@@ -421,6 +421,8 @@ static const struct pci_device_id ahci_p { PCI_VDEVICE(INTEL, 0x34d3), board_ahci_low_power }, /* Ice Lake LP AHCI */ { PCI_VDEVICE(INTEL, 0x02d3), board_ahci_low_power }, /* Comet Lake PCH-U AHCI */ { PCI_VDEVICE(INTEL, 0x02d7), board_ahci_low_power }, /* Comet Lake PCH RAID */ +/* Elkhart Lake IDs 0x4b60 & 0x4b62 https://sata-io.org/product/8803 not tested yet */ + { PCI_VDEVICE(INTEL, 0x4b63), board_ahci_low_power }, /* Elkhart Lake AHCI *//* JMicron 360/1/3/5/6, match class to avoid IDE function */ { PCI_VENDOR_ID_JMICRON, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
Greg Kroah-Hartman
maintainerPATCH 198/285 ata: pata_falcon: fix IO base selection for Q40
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Schmitz <[email protected]>
commit 8a1f00b753ecfdb117dc1a07e68c46d80e7923ea upstream.
With commit 44b1fbc0f5f3 ("m68k/q40: Replace q40ide driver with pata_falcon and falconide"), the Q40 IDE driver was replaced by pata_falcon.c.
Both IO and memory resources were defined for the Q40 IDE platform device, but definition of the IDE register addresses was modeled after the Falcon case, both in use of the memory resources and in including register shift and byte vs. word offset in the address.
This was correct for the Falcon case, which does not apply any address translation to the register addresses. In the Q40 case, all of device base address, byte access offset and register shift is included in the platform specific ISA access translation (in asm/mm_io.h).
As a consequence, such address translation gets applied twice, and register addresses are mangled.
Use the device base address from the platform IO resource for Q40 (the IO address translation will then add the correct ISA window base address and byte access offset), with register shift 1. Use MMIO base address and register shift 2 as before for Falcon.
Encode PIO_OFFSET into IO port addresses for all registers for Q40 except the data transfer register. Encode the MMIO offset there (pata_falcon_data_xfer() directly uses raw IO with no address translation).
--- drivers/ata/pata_falcon.c | 50 ++++++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 21 deletions(-)
drivers/ata/pata_falcon.c +29 -21
@@ -123,8 +123,8 @@ static int __init pata_falcon_init_one(sstruct resource *base_res, *ctl_res, *irq_res;struct ata_host *host;struct ata_port *ap; -void __iomem *base; -int irq =0 ; +void __iomem *base, *ctl_base; +int irq =0 , io_offset =1 , reg_shift =2 ;/* Falcon defaults */ dev_info (&pdev->dev,"Atari Falcon and Q40/Q60 PATA controller\n" );
@@ -165,26 +165,34 @@ static int __init pata_falcon_init_one(s ap->pio_mask =ATA_PIO4 ; ap->flags |=ATA_FLAG_SLAVE_POSS |ATA_FLAG_NO_IORDY ; - base = (void __iomem *)base_mem_res->start;/* N.B. this assumes data_addr will be used for word-sized I/O only */ - ap->ioaddr.data_addr = base +0 +0 *4 ; - ap->ioaddr.error_addr = base +1 +1 *4 ; - ap->ioaddr.feature_addr = base +1 +1 *4 ; - ap->ioaddr.nsect_addr = base +1 +2 *4 ; - ap->ioaddr.lbal_addr = base +1 +3 *4 ; - ap->ioaddr.lbam_addr = base +1 +4 *4 ; - ap->ioaddr.lbah_addr = base +1 +5 *4 ; - ap->ioaddr.device_addr = base +1 +6 *4 ; - ap->ioaddr.status_addr = base +1 +7 *4 ; - ap->ioaddr.command_addr = base +1 +7 *4 ; - - base = (void __iomem *)ctl_mem_res->start; - ap->ioaddr.altstatus_addr = base +1 ; - ap->ioaddr.ctl_addr = base +1 ; - -ata_port_desc (ap,"cmd 0x%lx ctl 0x%lx" , - (unsigned long )base_mem_res->start, - (unsigned long )ctl_mem_res->start); + ap->ioaddr.data_addr = (void __iomem *)base_mem_res->start; + +if (base_res) {/* only Q40 has IO resources */ + io_offset =0x10000 ; + reg_shift =0 ; + base = (void __iomem *)base_res->start; + ctl_base = (void __iomem *)ctl_res->start; + }else { + base = (void __iomem *)base_mem_res->start; + ctl_base = (void __iomem *)ctl_mem_res->start; + } + + ap->ioaddr.error_addr = base + io_offset + (1 << reg_shift); + ap->ioaddr.feature_addr = base + io_offset + (1 << reg_shift); + ap->ioaddr.nsect_addr = base + io_offset + (2 << reg_shift); + ap->ioaddr.lbal_addr = base + io_offset + (3 << reg_shift); + ap->ioaddr.lbam_addr = base + io_offset + (4 << reg_shift); + ap->ioaddr.lbah_addr = base + io_offset + (5 << reg_shift); + ap->ioaddr.device_addr = base + io_offset + (6 << reg_shift); + ap->ioaddr.status_addr = base + io_offset + (7 << reg_shift); + ap->ioaddr.command_addr = base + io_offset + (7 << reg_shift); + + ap->ioaddr.altstatus_addr = ctl_base + io_offset; + ap->ioaddr.ctl_addr = ctl_base + io_offset; + +ata_port_desc (ap,"cmd %px ctl %px data %px" , + base, ctl_base, ap->ioaddr.data_addr); irq_res =platform_get_resource (pdev,IORESOURCE_IRQ ,0 );if (irq_res && irq_res->start >0 ) {
Greg Kroah-Hartman
maintainerPATCH 199/285 ata: sata_gemini: Add missing MODULE_DESCRIPTION
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Damien Le Moal <[email protected]>
commit 8566572bf3b4d6e416a4bf2110dbb4817d11ba59 upstream.
Add the missing MODULE_DESCRIPTION() to avoid warnings such as:
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/ata/sata_gemini.o
when compiling with W=1.
--- drivers/ata/sata_gemini.c | 1 + 1 file changed, 1 insertion(+)
drivers/ata/sata_gemini.c +1 -0
@@ -428,6 +428,7 @@ static struct platform_driver gemini_sat };module_platform_driver (gemini_sata_driver); +MODULE_DESCRIPTION ("low level driver for Cortina Systems Gemini SATA bridge" );MODULE_AUTHOR ("Linus Walleij <[email protected]>" );MODULE_LICENSE ("GPL" );MODULE_ALIAS ("platform:" DRV_NAME );
Greg Kroah-Hartman
maintainerPATCH 200/285 ata: pata_ftide010: Add missing MODULE_DESCRIPTION
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Damien Le Moal <[email protected]>
commit 7274eef5729037300f29d14edeb334a47a098f65 upstream.
Add the missing MODULE_DESCRIPTION() to avoid warnings such as:
WARNING: modpost: missing MODULE_DESCRIPTION() in drivers/ata/pata_ftide010.o
when compiling with W=1.
--- drivers/ata/pata_ftide010.c | 1 + 1 file changed, 1 insertion(+)
drivers/ata/pata_ftide010.c +1 -0
@@ -567,6 +567,7 @@ static struct platform_driver pata_ftide };module_platform_driver (pata_ftide010_driver); +MODULE_DESCRIPTION ("low level driver for Faraday Technology FTIDE010" );MODULE_AUTHOR ("Linus Walleij <[email protected]>" );MODULE_LICENSE ("GPL" );MODULE_ALIAS ("platform:" DRV_NAME );
Greg Kroah-Hartman
maintainerPATCH 201/285 fuse: nlookup missing decrement in fuse_direntplus_link
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: ruanmeisi <[email protected]>
commit b8bd342d50cbf606666488488f9fea374aceb2d5 upstream.
During our debugging of glusterfs, we found an Assertion failed error:inode_lookup >= nlookup, which was caused by the nlookup value in the kernel being greater than that in the FUSE file system.
The issue was introduced by fuse_direntplus_link, where in the function, fuse_iget increments nlookup, and if d_splice_alias returns failure, fuse_direntplus_link returns failure without decrementing nlookup
https://github.com/gluster/glusterfs/pull/4081
--- fs/fuse/readdir.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-)
fs/fuse/readdir.c +9 -1
@@ -243,8 +243,16 @@ retry:dput (dentry); dentry = alias; } -if (IS_ERR (dentry)) +if (IS_ERR (dentry)) { +if (!IS_ERR (inode)) { +struct fuse_inode *fi =get_fuse_inode (inode); + +spin_lock (&fi->lock); + fi->nlookup--; +spin_unlock (&fi->lock); + }return PTR_ERR (dentry); + } }if (fc->readdirplus_auto)set_bit (FUSE_I_INIT_RDPLUS , &get_fuse_inode (inode)->state);
Greg Kroah-Hartman
maintainerPATCH 202/285 btrfs: zoned: do not zone finish data relocation block group
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Naohiro Aota <[email protected]>
commit 332581bde2a419d5f12a93a1cdc2856af649a3cc upstream.
When multiple writes happen at once, we may need to sacrifice a currently active block group to be zone finished for a new allocation. We choose a block group with the least free space left, and zone finish it.
To do the finishing, we need to send IOs for already allocated region and wait for them and on-going IOs. Otherwise, these IOs fail because the zone is already finished at the time the IO reach a device.
However, if a block group dedicated to the data relocation is zone finished, there is a chance that finishing it before an ongoing write IO reaches the device. That is because there is timing gap between an allocation is done (block_group->reservations == 0, as pre-allocation is done) and an ordered extent is created when the relocation IO starts. Thus, if we finish the zone between them, we can fail the IOs.
We cannot simply use "fs_info->data_reloc_bg == block_group->start" to avoid the zone finishing. Because, the data_reloc_bg may already switch to a new block group, while there are still ongoing write IOs to the old data_reloc_bg.
So, this patch reworks the BLOCK_GROUP_FLAG_ZONED_DATA_RELOC bit to indicate there is a data relocation allocation and/or ongoing write to the block group. The bit is set on allocation and cleared in end_io function of the last IO for the currently allocated region.
To change the timing of the bit setting also solves the issue that the bit being left even after there is no IO going on. With the current code, if the data_reloc_bg switches after the last IO to the current data_reloc_bg, the bit is set at this timing and there is no one clearing that bit. As a result, that block group is kept unallocatable for anything.
--- fs/btrfs/extent-tree.c | 43 +++++++++++++++++++++++-------------------- fs/btrfs/zoned.c | 16 +++++++++++++--- 2 files changed, 36 insertions(+), 23 deletions(-)
fs/btrfs/extent-tree.c +23 -20
@@ -3709,7 +3709,8 @@ static int do_allocation_zoned(struct bt fs_info->data_reloc_bg == 0);if (block_group->ro || -test_bit (BLOCK_GROUP_FLAG_ZONED_DATA_RELOC , &block_group->runtime_flags)) { + (!ffe_ctl->for_data_reloc && +test_bit (BLOCK_GROUP_FLAG_ZONED_DATA_RELOC , &block_group->runtime_flags))) { ret =1 ; goto out; }
@@ -3752,8 +3753,26 @@ static int do_allocation_zoned(struct btif (ffe_ctl->for_treelog && !fs_info->treelog_bg) fs_info->treelog_bg = block_group->start; -if (ffe_ctl->for_data_reloc && !fs_info->data_reloc_bg) - fs_info->data_reloc_bg = block_group->start; +if (ffe_ctl->for_data_reloc) { +if (!fs_info->data_reloc_bg) + fs_info->data_reloc_bg = block_group->start; +/* +* Do not allow allocations from this block group, unless it is +* for data relocation. Compared to increasing the ->ro, setting +* the ->zoned_data_reloc_ongoing flag still allows nocow +* writers to come in. See btrfs_inc_nocow_writers(). +* +* We need to disable an allocation to avoid an allocation of +* regular (non-relocation data) extent. With mix of relocation +* extents and regular extents, we can dispatch WRITE commands +* (for relocation extents) and ZONE APPEND commands (for +* regular extents) at the same time to the same zone, which +* easily break the write pointer. +* +* Also, this flag avoids this block group to be zone finished. +*/ +set_bit (BLOCK_GROUP_FLAG_ZONED_DATA_RELOC , &block_group->runtime_flags); + } ffe_ctl->found_offset = start + block_group->alloc_offset; block_group->alloc_offset += num_bytes;
@@ -3771,24 +3790,8 @@ static int do_allocation_zoned(struct bt out:if (ret && ffe_ctl->for_treelog) fs_info->treelog_bg =0 ; -if (ret && ffe_ctl->for_data_reloc && - fs_info->data_reloc_bg == block_group->start) { -/* -* Do not allow further allocations from this block group. -* Compared to increasing the ->ro, setting the -* ->zoned_data_reloc_ongoing flag still allows nocow -* writers to come in. See btrfs_inc_nocow_writers(). -* -* We need to disable an allocation to avoid an allocation of -* regular (non-relocation data) extent. With mix of relocation -* extents and regular extents, we can dispatch WRITE commands -* (for relocation extents) and ZONE APPEND commands (for -* regular extents) at the same time to the same zone, which -* easily break the write pointer. -*/ -set_bit (BLOCK_GROUP_FLAG_ZONED_DATA_RELOC , &block_group->runtime_flags); +if (ret && ffe_ctl->for_data_reloc) fs_info->data_reloc_bg =0 ; - }spin_unlock (&fs_info->relocation_bg_lock);spin_unlock (&fs_info->treelog_bg_lock);spin_unlock (&block_group->lock);
fs/btrfs/zoned.c +13 -3
@@ -2017,6 +2017,10 @@ static int do_zone_finish(struct btrfs_b* and block_group->meta_write_pointer for metadata. */ if (!fully_written) { +if (test_bit (BLOCK_GROUP_FLAG_ZONED_DATA_RELOC , &block_group->runtime_flags)) { +spin_unlock (&block_group->lock); +return -EAGAIN ; + }spin_unlock (&block_group->lock); ret =btrfs_inc_block_group_ro (block_group, false);
@@ -2045,7 +2049,9 @@ static int do_zone_finish(struct btrfs_breturn 0 ; } -if (block_group->reserved) { +if (block_group->reserved || +test_bit (BLOCK_GROUP_FLAG_ZONED_DATA_RELOC , + &block_group->runtime_flags)) {spin_unlock (&block_group->lock);btrfs_dec_block_group_ro (block_group);return -EAGAIN ;
@@ -2276,7 +2282,10 @@ void btrfs_zoned_release_data_reloc_bg(s/* All relocation extents are written. */ if (block_group->start + block_group->alloc_offset == logical + length) { -/* Now, release this block group for further allocations. */ +/* +* Now, release this block group for further allocations and +* zone finish. +*/ clear_bit (BLOCK_GROUP_FLAG_ZONED_DATA_RELOC , &block_group->runtime_flags); }
@@ -2300,7 +2309,8 @@ int btrfs_zone_finish_one_bg(struct btrfspin_lock (&block_group->lock);if (block_group->reserved || block_group->alloc_offset ==0 || - (block_group->flags &BTRFS_BLOCK_GROUP_SYSTEM )) { + (block_group->flags &BTRFS_BLOCK_GROUP_SYSTEM ) || +test_bit (BLOCK_GROUP_FLAG_ZONED_DATA_RELOC , &block_group->runtime_flags)) {spin_unlock (&block_group->lock);continue ; }
Greg Kroah-Hartman
maintainerPATCH 203/285 btrfs: fix start transaction qgroup rsv double free
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Boris Burkov <[email protected]>
commit a6496849671a5bc9218ecec25a983253b34351b1 upstream.
btrfs_start_transaction reserves metadata space of the PERTRANS type before it identifies a transaction to start/join. This allows flushing when reserving that space without a deadlock. However, it results in a race which temporarily breaks qgroup rsv accounting.
T1 T2start_transactiondo_stuff
start_transaction
qgroup_reserve_meta_pertranscommit_transaction
qgroup_free_meta_all_pertrans
hit an error starting txn goto reserve_fail qgroup_free_meta_pertrans (already freed!)
The basic issue is that there is nothing preventing another commit from committing before start_transaction finishes (in fact sometimes we intentionally wait for it) so any error path that frees the reserve is at risk of this race.
While this exact space was getting freed anyway, and it's not a huge deal to double free it (just a warning, the free code catches this), it can result in incorrectly freeing some other pertrans reservation in this same reservation, which could then lead to spuriously granting reservations we might not have the space for. Therefore, I do believe it is worth fixing.
To fix it, use the existing prealloc->pertrans conversion mechanism. When we first reserve the space, we reserve prealloc space and only when we are sure we have a transaction do we convert it to pertrans. This way any racing commits do not blow away our reservation, but we still get a pertrans reservation that is freed when _this_ transaction gets committed.
This issue can be reproduced by running generic/269 with either qgroups or squotas enabled via mkfs on the scratch device.
--- fs/btrfs/transaction.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-)
fs/btrfs/transaction.c +16 -3
@@ -591,8 +591,13 @@ start_transaction(struct btrfs_root *roou64 delayed_refs_bytes =0 ; qgroup_reserved = num_items * fs_info->nodesize; - ret =btrfs_qgroup_reserve_meta_pertrans (root, qgroup_reserved, - enforce_qgroups); +/* +* Use prealloc for now, as there might be a currently running +* transaction that could free this reserved space prematurely +* by committing. +*/ + ret =btrfs_qgroup_reserve_meta_prealloc (root, qgroup_reserved, + enforce_qgroups, false);if (ret)return ERR_PTR (ret);
@@ -705,6 +710,14 @@ again: h->reloc_reserved = reloc_reserved; } +/* +* Now that we have found a transaction to be a part of, convert the +* qgroup reservation from prealloc to pertrans. A different transaction +* can't race in and free our pertrans out from under us. +*/ +if (qgroup_reserved) +btrfs_qgroup_convert_reserved_meta (root, qgroup_reserved); + got_it:if (!current->journal_info) current->journal_info = h;
@@ -752,7 +765,7 @@ alloc_fail:btrfs_block_rsv_release (fs_info, &fs_info->trans_block_rsv, num_bytes,NULL ); reserve_fail: -btrfs_qgroup_free_meta_pertrans (root, qgroup_reserved); +btrfs_qgroup_free_meta_prealloc (root, qgroup_reserved);return ERR_PTR (ret); }
Greg Kroah-Hartman
maintainerPATCH 204/285 btrfs: free qgroup rsv on io failure
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Boris Burkov <[email protected]>
commit e28b02118b94e42be3355458a2406c6861e2dd32 upstream.
If we do a write whose bio suffers an error, we will never reclaim the qgroup reserved space for it. We allocate the space in the write_iter codepath, then release the reservation as we allocate the ordered extent, but we only create a delayed ref if the ordered extent finishes. If it has an error, we simply leak the rsv. This is apparent in running any error injecting (dmerror) fstests like btrfs/146 or btrfs/160. Such tests fail due to dmesg on umount complaining about the leaked qgroup data space.
When we clean up other aspects of space on failed ordered_extents, also free the qgroup rsv.
--- fs/btrfs/inode.c | 7 +++++++ 1 file changed, 7 insertions(+)
fs/btrfs/inode.c +7 -0
@@ -3359,6 +3359,13 @@ out:btrfs_free_reserved_extent (fs_info, ordered_extent->disk_bytenr, ordered_extent->disk_num_bytes,1 ); +/* +* Actually free the qgroup rsv which was released when +* the ordered extent was created. +*/ +btrfs_qgroup_free_refroot (fs_info, inode->root->root_key.objectid, + ordered_extent->qgroup_rsv, +BTRFS_QGROUP_RSV_DATA ); } }
Greg Kroah-Hartman
maintainerPATCH 205/285 btrfs: dont start transaction when joining with TRANS_JOIN_NOSTART
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <[email protected]>
commit 4490e803e1fe9fab8db5025e44e23b55df54078b upstream.
When joining a transaction with TRANS_JOIN_NOSTART, if we don't find a running transaction we end up creating one. This goes against the purpose of TRANS_JOIN_NOSTART which is to join a running transaction if its state is at or below the state TRANS_STATE_COMMIT_START, otherwise return an -ENOENT error and don't start a new transaction. So fix this to not create a new transaction if there's no running transaction at or below that state.
--- fs/btrfs/transaction.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
fs/btrfs/transaction.c +4 -3
@@ -292,10 +292,11 @@ loop:spin_unlock (&fs_info->trans_lock);/* -* If we are ATTACH, we just want to catch the current transaction, -* and commit it. If there is no transaction, just return ENOENT. +* If we are ATTACH or TRANS_JOIN_NOSTART, we just want to catch the +* current transaction, and commit it. If there is no transaction, just +* return ENOENT. */ -if (type ==TRANS_ATTACH ) +if (type ==TRANS_ATTACH || type ==TRANS_JOIN_NOSTART )return -ENOENT ;/*
Greg Kroah-Hartman
maintainerPATCH 206/285 btrfs: set page extent mapped after read_folio in relocate_one_page
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josef Bacik <[email protected]>
commit e7f1326cc24e22b38afc3acd328480a1183f9e79 upstream.
One of the CI runs triggered the following panic
assertion failed: PagePrivate(page) && page->private, in fs/btrfs/subpage.c:229
------------[ cut here ]------------ kernel BUG at fs/btrfs/subpage.c:229! Internal error: Oops - BUG: 00000000f2000800 [#1] SMP CPU: 0 PID: 923660 Comm: btrfs Not tainted 6.5.0-rc3+ #1 pstate: 61400005 (nZCv daif +PAN -UAO -TCO +DIT -SSBS BTYPE=--) pc : btrfs_subpage_assert+0xbc/0xf0 lr : btrfs_subpage_assert+0xbc/0xf0 sp : ffff800093213720 x29: ffff800093213720 x28: ffff8000932138b4 x27: 000000000c280000 x26: 00000001b5d00000 x25: 000000000c281000 x24: 000000000c281fff x23: 0000000000001000 x22: 0000000000000000 x21: ffffff42b95bf880 x20: ffff42b9528e0000 x19: 0000000000001000 x18: ffffffffffffffff x17: 667274622f736620 x16: 6e69202c65746176 x15: 0000000000000028 x14: 0000000000000003 x13: 00000000002672d7 x12: 0000000000000000 x11: ffffcd3f0ccd9204 x10: ffffcd3f0554ae50 x9 : ffffcd3f0379528c x8 : ffff800093213428 x7 : 0000000000000000 x6 : ffffcd3f091771e8 x5 : ffff42b97f333948 x4 : 0000000000000000 x3 : 0000000000000000 x2 : 0000000000000000 x1 : ffff42b9556cde80 x0 : 000000000000004f Call trace: btrfs_subpage_assert+0xbc/0xf0 btrfs_subpage_set_dirty+0x38/0xa0 btrfs_page_set_dirty+0x58/0x88 relocate_one_page+0x204/0x5f0 relocate_file_extent_cluster+0x11c/0x180 relocate_data_extent+0xd0/0xf8 relocate_block_group+0x3d0/0x4e8 btrfs_relocate_block_group+0x2d8/0x490 btrfs_relocate_chunk+0x54/0x1a8 btrfs_balance+0x7f4/0x1150 btrfs_ioctl+0x10f0/0x20b8 __arm64_sys_ioctl+0x120/0x11d8 invoke_syscall.constprop.0+0x80/0xd8 do_el0_svc+0x6c/0x158 el0_svc+0x50/0x1b0 el0t_64_sync_handler+0x120/0x130 el0t_64_sync+0x194/0x198 Code: 91098021 b0007fa0 91346000 97e9c6d2 (d4210000)
This is the same problem outlined in 17b17fcd6d44 ("btrfs:set_page_extent_mapped after read_folio in btrfs_cont_expand") , and the fix is the same. I originally looked for the same pattern elsewhere in our code, but mistakenly skipped over this code because I saw the page cache readahead before we set_page_extent_mapped, not realizing that this was only in the !page case, that we can still end up with a !uptodate page and then do the btrfs_read_folio further down.
The fix here is the same as the above mentioned patch, move the set_page_extent_mapped call to after the btrfs_read_folio() block to make sure that we have the subpage blocksize stuff setup properly before using the page.
--- fs/btrfs/relocation.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-)
fs/btrfs/relocation.c +9 -3
@@ -3006,9 +3006,6 @@ static int relocate_one_page(struct inodif (!page)return -ENOMEM ; } - ret =set_page_extent_mapped (page); -if (ret <0 ) - goto release_page;if (PageReadahead (page)) page_cache_async_readahead(inode->i_mapping, ra, NULL,
@@ -3024,6 +3021,15 @@ static int relocate_one_page(struct inod } } +/* +* We could have lost page private when we dropped the lock to read the +* page above, make sure we set_page_extent_mapped here so we have any +* of the subpage blocksize stuff we need in place. +*/ + ret =set_page_extent_mapped (page); +if (ret <0 ) + goto release_page; + page_start =page_offset (page); page_end = page_start +PAGE_SIZE -1 ;
Greg Kroah-Hartman
maintainerPATCH 207/285 btrfs: zoned: re-enable metadata over-commit for zoned mode
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Naohiro Aota <[email protected]>
commit 5b135b382a360f4c87cf8896d1465b0b07f10cb0 upstream.
Now that, we can re-enable metadata over-commit. As we moved the activation from the reservation time to the write time, we no longer need to ensure all the reserved bytes is properly activated.
Without the metadata over-commit, it suffers from lower performance because it needs to flush the delalloc items more often and allocate more block groups. Re-enabling metadata over-commit will solve the issue.
--- fs/btrfs/space-info.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-)
fs/btrfs/space-info.c +1 -5
@@ -389,11 +389,7 @@ int btrfs_can_overcommit(struct btrfs_fsreturn 0 ; used =btrfs_space_info_used (space_info, true); -if (test_bit (BTRFS_FS_ACTIVE_ZONE_TRACKING , &fs_info->flags) && - (space_info->flags &BTRFS_BLOCK_GROUP_METADATA )) - avail =0 ; -else - avail =calc_available_free_space (fs_info, space_info, flush); + avail =calc_available_free_space (fs_info, space_info, flush);if (used + bytes < space_info->total_bytes + avail)return 1 ;
Greg Kroah-Hartman
maintainerPATCH 208/285 btrfs: use the correct superblock to compare fsid in btrfs_validate_super
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Anand Jain <[email protected]>
commit d167aa76dc0683828588c25767da07fb549e4f48 upstream.
The function btrfs_validate_super() should verify the fsid in the provided superblock argument. Because, all its callers expect it to do that.
Such as in the following stack:
write_all_supers()
sb = fs_info->super_for_commit;
btrfs_validate_write_super(.., sb)
btrfs_validate_super(.., sb, ..) scrub_one_super()
btrfs_validate_super(.., sb, ..)
And
check_dev_super()
btrfs_validate_super(.., sb, ..)
However, it currently verifies the fs_info::super_copy::fsid instead, which is not correct. Fix this using the correct fsid in the superblock argument.
--- fs/btrfs/disk-io.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
fs/btrfs/disk-io.c +2 -3
@@ -2384,11 +2384,10 @@ int btrfs_validate_super(struct btrfs_fs ret = -EINVAL ; } -if (memcmp (fs_info->fs_devices->fsid, fs_info->super_copy->fsid, -BTRFS_FSID_SIZE )) { +if (memcmp (fs_info->fs_devices->fsid, sb->fsid,BTRFS_FSID_SIZE ) !=0 ) {btrfs_err (fs_info,"superblock fsid doesn't match fsid of fs_devices: %pU != %pU" , - fs_info->super_copy->fsid, fs_info->fs_devices->fsid); + sb->fsid, fs_info->fs_devices->fsid); ret = -EINVAL ; }
Greg Kroah-Hartman
maintainerPATCH 209/285 btrfs: scrub: avoid unnecessary extent tree search preparing stripes
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qu Wenruo <[email protected]>
commit 1dc4888e725dc748b82858984f2a5bd41efc5201 upstream.
Since commit e02ee89baa66 ("btrfs: scrub: switch scrub_simple_mirror() to scrub_stripe infrastructure"), scrub no longer re-use the same path for extent tree search.
This can lead to unnecessary extent tree search, especially for the new stripe based scrub, as we have way more stripes to prepare.
This patch would re-introduce a shared path for extent tree search, and properly release it when the block group is scrubbed.
This change alone can improve scrub performance slightly by reducing the time spend preparing the stripe thus improving the queue depth.
Before (with regression):
Device r/s rkB/s rrqm/s %rrqm r_await rareq-sz aqu-sz %util
nvme0n1p3 15578.00 993616.00 5.00 0.03 0.09 63.78 1.32 100.00
After (with this patch):
nvme0n1p3 15875.00 1013328.00 12.00 0.08 0.08 63.83 1.35 100.00
--- fs/btrfs/scrub.c | 41 +++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-)
fs/btrfs/scrub.c +29 -12
@@ -175,6 +175,7 @@ struct scrub_ctx {struct scrub_stripe stripes[SCRUB_STRIPES_PER_SCTX ];struct scrub_stripe *raid56_data_stripes;struct btrfs_fs_info *fs_info; +struct btrfs_path extent_path;int first_free;int cur_stripe;atomic_t cancel_req;
@@ -339,6 +340,8 @@ static noinline_for_stack struct scrub_crefcount_set (&sctx->refs,1 ); sctx->is_dev_replace = is_dev_replace; sctx->fs_info = fs_info; + sctx->extent_path.search_commit_root =1 ; + sctx->extent_path.skip_locking =1 ;for (i =0 ; i <SCRUB_STRIPES_PER_SCTX ; i++) {int ret;
@@ -1468,6 +1471,7 @@ static void scrub_stripe_reset_bitmaps(s* Return <0 for error. */ static int scrub_find_fill_first_stripe(struct btrfs_block_group *bg, + struct btrfs_path *extent_path, struct btrfs_device *dev, u64 physical, int mirror_num, u64 logical_start, u32 logical_len,
@@ -1477,7 +1481,6 @@ static int scrub_find_fill_first_stripe(struct btrfs_root *extent_root =btrfs_extent_root (fs_info, bg->start);struct btrfs_root *csum_root =btrfs_csum_root (fs_info, bg->start);const u64 logical_end = logical_start + logical_len; -struct btrfs_path path = {0 };u64 cur_logical = logical_start;u64 stripe_end;u64 extent_start;
@@ -1493,14 +1496,13 @@ static int scrub_find_fill_first_stripe(/* The range must be inside the bg. */ ASSERT (logical_start >= bg->start && logical_end <= bg->start + bg->length); - path.search_commit_root =1 ; - path.skip_locking =1 ; - - ret =find_first_extent_item (extent_root, &path, logical_start, logical_len); + ret =find_first_extent_item (extent_root, extent_path, logical_start, + logical_len);/* Either error or not found. */ if (ret) goto out; -get_extent_info (&path, &extent_start, &extent_len, &extent_flags, &extent_gen); +get_extent_info (extent_path, &extent_start, &extent_len, &extent_flags, + &extent_gen);if (extent_flags &BTRFS_EXTENT_FLAG_TREE_BLOCK ) stripe->nr_meta_extents++;if (extent_flags &BTRFS_EXTENT_FLAG_DATA )
@@ -1528,7 +1530,7 @@ static int scrub_find_fill_first_stripe(/* Fill the extent info for the remaining sectors. */ while (cur_logical <= stripe_end) { - ret =find_first_extent_item (extent_root, &path, cur_logical, + ret =find_first_extent_item (extent_root, extent_path, cur_logical, stripe_end - cur_logical +1 );if (ret <0 ) goto out;
@@ -1536,7 +1538,7 @@ static int scrub_find_fill_first_stripe( ret =0 ;break ; } -get_extent_info (&path, &extent_start, &extent_len, +get_extent_info (extent_path, &extent_start, &extent_len, &extent_flags, &extent_gen);if (extent_flags &BTRFS_EXTENT_FLAG_TREE_BLOCK ) stripe->nr_meta_extents++;
@@ -1576,7 +1578,6 @@ static int scrub_find_fill_first_stripe( }set_bit (SCRUB_STRIPE_FLAG_INITIALIZED , &stripe->state); out: -btrfs_release_path (&path);return ret; }
@@ -1766,8 +1767,9 @@ static int queue_scrub_stripe(struct scr/* We can queue one stripe using the remaining slot. */ scrub_reset_stripe (stripe); - ret =scrub_find_fill_first_stripe (bg, dev, physical, mirror_num, - logical, length, stripe); + ret =scrub_find_fill_first_stripe (bg, &sctx->extent_path, dev, + physical, mirror_num, logical, + length, stripe);/* Either >0 as no more extents or <0 for error. */ if (ret)return ret;
@@ -1785,6 +1787,7 @@ static int scrub_raid56_parity_stripe(ststruct btrfs_fs_info *fs_info = sctx->fs_info;struct btrfs_raid_bio *rbio;struct btrfs_io_context *bioc =NULL ; +struct btrfs_path extent_path = {0 };struct bio *bio;struct scrub_stripe *stripe;bool all_empty = true;
@@ -1795,6 +1798,14 @@ static int scrub_raid56_parity_stripe(stASSERT (sctx->raid56_data_stripes); +/* +* For data stripe search, we cannot re-use the same extent path, as +* the data stripe bytenr may be smaller than previous extent. Thus we +* have to use our own extent path. +*/ + extent_path.search_commit_root =1 ; + extent_path.skip_locking =1 ; +for (int i =0 ; i < data_stripes; i++) {int stripe_index;int rot;
@@ -1809,7 +1820,7 @@ static int scrub_raid56_parity_stripe(stscrub_reset_stripe (stripe);set_bit (SCRUB_STRIPE_FLAG_NO_REPORT , &stripe->state); - ret =scrub_find_fill_first_stripe (bg, + ret =scrub_find_fill_first_stripe (bg, &extent_path, map->stripes[stripe_index].dev, physical,1 , full_stripe_start +btrfs_stripe_nr_to_offset (i),BTRFS_STRIPE_LEN , stripe);
@@ -1937,6 +1948,7 @@ static int scrub_raid56_parity_stripe(stbio_put (bio);btrfs_bio_counter_dec (fs_info); +btrfs_release_path (&extent_path); out:return ret; }
@@ -2109,6 +2121,9 @@ static noinline_for_stack int scrub_striu64 stripe_logical;int stop_loop =0 ; +/* Extent_path should be released by now. */ +ASSERT (sctx->extent_path.nodes[0 ] ==NULL ); +scrub_blocked_if_needed (fs_info); if (sctx->is_dev_replace &&
@@ -2227,6 +2242,8 @@ out: ret2 =flush_scrub_stripes (sctx);if (!ret) ret = ret2; +btrfs_release_path (&sctx->extent_path); +if (sctx->raid56_data_stripes) {for (int i =0 ; i <nr_data_stripes (map); i++)release_scrub_stripe (&sctx->raid56_data_stripes[i]);
Greg Kroah-Hartman
maintainerPATCH 210/285 btrfs: scrub: avoid unnecessary csum tree search preparing stripes
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qu Wenruo <[email protected]>
commit 3c771c194402ffe20d4de68d9fc21e703179a9ce upstream.
One of the bottleneck of the new scrub code is the extra csum tree search.
The old code would only do the csum tree search for each scrub bio, which can be as large as 512KiB, thus they can afford to allocate a new path each time.
But the new scrub code is doing csum tree search for each stripe, which is only 64KiB, this means we'd better re-use the same csum path during each search.
This patch would introduce a per-sctx path for csum tree search, as we don't need to re-allocate the path every time we need to do a csum tree search.
With this change we can further improve the queue depth and improve the scrub read performance:
Before (with regression and cached extent tree path):
Device r/s rkB/s rrqm/s %rrqm r_await rareq-sz aqu-sz %util
nvme0n1p3 15875.00 1013328.00 12.00 0.08 0.08 63.83 1.35 100.00
After (with both cached extent/csum tree path):
nvme0n1p3 17759.00 1133280.00 10.00 0.06 0.08 63.81 1.50 100.00
--- fs/btrfs/file-item.c | 36 +++++++++++++++++++++++------------- fs/btrfs/file-item.h | 6 +++--- fs/btrfs/raid56.c | 4 ++-- fs/btrfs/scrub.c | 29 +++++++++++++++++++---------- 4 files changed, 47 insertions(+), 28 deletions(-)
fs/btrfs/file-item.c +23 -13
@@ -597,29 +597,37 @@ fail:* Each bit represents a sector. Thus caller should ensure @csum_buf passed * in is large enough to contain all csums. */ -int btrfs_lookup_csums_bitmap (struct btrfs_root *root,u64 start,u64 end, -u8 *csum_buf,unsigned long *csum_bitmap, -bool search_commit) +int btrfs_lookup_csums_bitmap (struct btrfs_root *root,struct btrfs_path *path, +u64 start,u64 end,u8 *csum_buf, +unsigned long *csum_bitmap) {struct btrfs_fs_info *fs_info = root->fs_info;struct btrfs_key key; -struct btrfs_path *path;struct extent_buffer *leaf;struct btrfs_csum_item *item;const u64 orig_start = start; +bool free_path = false;int ret;ASSERT (IS_ALIGNED (start, fs_info->sectorsize) &&IS_ALIGNED (end +1 , fs_info->sectorsize)); - path =btrfs_alloc_path (); -if (!path) -return -ENOMEM ; - -if (search_commit) { - path->skip_locking =1 ; - path->reada =READA_FORWARD ; - path->search_commit_root =1 ; +if (!path) { + path =btrfs_alloc_path (); +if (!path) +return -ENOMEM ; + free_path = true; + } + +/* Check if we can reuse the previous path. */ +if (path->nodes[0 ]) { +btrfs_item_key_to_cpu (path->nodes[0 ], &key, path->slots[0 ]); + +if (key.objectid ==BTRFS_EXTENT_CSUM_OBJECTID && + key.type ==BTRFS_EXTENT_CSUM_KEY && + key.offset <= start) + goto search_forward; +btrfs_release_path (path); } key.objectid =BTRFS_EXTENT_CSUM_OBJECTID ;
@@ -656,6 +664,7 @@ int btrfs_lookup_csums_bitmap(struct btr } } +search_forward:while (start <= end) {u64 csum_end;
@@ -712,7 +721,8 @@ int btrfs_lookup_csums_bitmap(struct btr } ret =0 ; fail: -btrfs_free_path (path); +if (free_path) +btrfs_free_path (path);return ret; }
fs/btrfs/file-item.h +3 -3
@@ -57,9 +57,9 @@ int btrfs_lookup_csums_range(struct btrfint btrfs_lookup_csums_list (struct btrfs_root *root,u64 start,u64 end,struct list_head *list,int search_commit,bool nowait); -int btrfs_lookup_csums_bitmap (struct btrfs_root *root,u64 start,u64 end, -u8 *csum_buf,unsigned long *csum_bitmap, -bool search_commit); +int btrfs_lookup_csums_bitmap (struct btrfs_root *root,struct btrfs_path *path, +u64 start,u64 end,u8 *csum_buf, +unsigned long *csum_bitmap); void btrfs_extent_item_to_extent_map(struct btrfs_inode *inode, const struct btrfs_path *path, struct btrfs_file_extent_item *fi,
fs/btrfs/raid56.c +2 -2
@@ -2112,8 +2112,8 @@ static void fill_data_csums(struct btrfs goto error; } - ret =btrfs_lookup_csums_bitmap (csum_root, start, start + len -1 , - rbio->csum_buf, rbio->csum_bitmap, false); + ret =btrfs_lookup_csums_bitmap (csum_root,NULL , start, start + len -1 , + rbio->csum_buf, rbio->csum_bitmap);if (ret <0 ) goto error;if (bitmap_empty (rbio->csum_bitmap, len >> fs_info->sectorsize_bits))
fs/btrfs/scrub.c +19 -10
@@ -176,6 +176,7 @@ struct scrub_ctx {struct scrub_stripe *raid56_data_stripes;struct btrfs_fs_info *fs_info;struct btrfs_path extent_path; +struct btrfs_path csum_path;int first_free;int cur_stripe;atomic_t cancel_req;
@@ -342,6 +343,8 @@ static noinline_for_stack struct scrub_c sctx->fs_info = fs_info; sctx->extent_path.search_commit_root =1 ; sctx->extent_path.skip_locking =1 ; + sctx->csum_path.search_commit_root =1 ; + sctx->csum_path.skip_locking =1 ;for (i =0 ; i <SCRUB_STRIPES_PER_SCTX ; i++) {int ret;
@@ -1472,6 +1475,7 @@ static void scrub_stripe_reset_bitmaps(s*/ static int scrub_find_fill_first_stripe(struct btrfs_block_group *bg, struct btrfs_path *extent_path, + struct btrfs_path *csum_path, struct btrfs_device *dev, u64 physical, int mirror_num, u64 logical_start, u32 logical_len,
@@ -1563,9 +1567,9 @@ static int scrub_find_fill_first_stripe(*/ ASSERT (BITS_PER_LONG >=BTRFS_STRIPE_LEN >> fs_info->sectorsize_bits); - ret =btrfs_lookup_csums_bitmap (csum_root, stripe->logical, - stripe_end, stripe->csums, - &csum_bitmap, true); + ret =btrfs_lookup_csums_bitmap (csum_root, csum_path, + stripe->logical, stripe_end, + stripe->csums, &csum_bitmap);if (ret <0 ) goto out;if (ret >0 )
@@ -1767,9 +1771,9 @@ static int queue_scrub_stripe(struct scr/* We can queue one stripe using the remaining slot. */ scrub_reset_stripe (stripe); - ret =scrub_find_fill_first_stripe (bg, &sctx->extent_path, dev, - physical, mirror_num, logical, - length, stripe); + ret =scrub_find_fill_first_stripe (bg, &sctx->extent_path, + &sctx->csum_path, dev, physical, + mirror_num, logical, length, stripe);/* Either >0 as no more extents or <0 for error. */ if (ret)return ret;
@@ -1788,6 +1792,7 @@ static int scrub_raid56_parity_stripe(ststruct btrfs_raid_bio *rbio;struct btrfs_io_context *bioc =NULL ;struct btrfs_path extent_path = {0 }; +struct btrfs_path csum_path = {0 };struct bio *bio;struct scrub_stripe *stripe;bool all_empty = true;
@@ -1799,12 +1804,14 @@ static int scrub_raid56_parity_stripe(stASSERT (sctx->raid56_data_stripes);/* -* For data stripe search, we cannot re-use the same extent path, as -* the data stripe bytenr may be smaller than previous extent. Thus we -* have to use our own extent path. +* For data stripe search, we cannot re-use the same extent/csum paths, +* as the data stripe bytenr may be smaller than previous extent. Thus +* we have to use our own extent/csum paths. */ extent_path.search_commit_root =1 ; extent_path.skip_locking =1 ; + csum_path.search_commit_root =1 ; + csum_path.skip_locking =1 ;for (int i =0 ; i < data_stripes; i++) {int stripe_index;
@@ -1820,7 +1827,7 @@ static int scrub_raid56_parity_stripe(stscrub_reset_stripe (stripe);set_bit (SCRUB_STRIPE_FLAG_NO_REPORT , &stripe->state); - ret =scrub_find_fill_first_stripe (bg, &extent_path, + ret =scrub_find_fill_first_stripe (bg, &extent_path, &csum_path, map->stripes[stripe_index].dev, physical,1 , full_stripe_start +btrfs_stripe_nr_to_offset (i),BTRFS_STRIPE_LEN , stripe);
@@ -1949,6 +1956,7 @@ static int scrub_raid56_parity_stripe(stbtrfs_bio_counter_dec (fs_info);btrfs_release_path (&extent_path); +btrfs_release_path (&csum_path); out:return ret; }
@@ -2243,6 +2251,7 @@ out:if (!ret) ret = ret2;btrfs_release_path (&sctx->extent_path); +btrfs_release_path (&sctx->csum_path);if (sctx->raid56_data_stripes) {for (int i =0 ; i <nr_data_stripes (map); i++)
Greg Kroah-Hartman
maintainerPATCH 211/285 btrfs: scrub: fix grouping of read IO
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qu Wenruo <[email protected]>
commit ae76d8e3e1351aa1ba09cc68dab6866d356f2e17 upstream.
[REGRESSION]
There are several regression reports about the scrub performance with v6.4 kernel.
On a PCIe 3.0 device, the old v6.3 kernel can go 3GB/s scrub speed, but v6.4 can only go 1GB/s, an obvious 66% performance drop.
[CAUSE]
Iostat shows a very different behavior between v6.3 and v6.4 kernel:
Device r/s rkB/s rrqm/s %rrqm r_await rareq-sz aqu-sz %util
nvme0n1p3 9731.00 3425544.00 17237.00 63.92 2.18 352.02 21.18 100.00
nvme0n1p3 15578.00 993616.00 5.00 0.03 0.09 63.78 1.32 100.00
The upper one is v6.3 while the lower one is v6.4.
There are several obvious differences:
- Very few read merges
This turns out to be a behavior change that we no longer do bio plug/unplug.
- Very low aqu-sz
This is due to the submit-and-wait behavior of flush_scrub_stripes(), and extra extent/csum tree search.
Both behaviors are not that obvious on SATA SSDs, as SATA SSDs have NCQ to merge the reads, while SATA SSDs can not handle high queue depth well either.
[FIX]
For now this patch focuses on the read speed fix. Dev-replace replace speed needs more work.
For the read part, we go two directions to fix the problems:
- Re-introduce blk plug/unplug to merge read requests This is pretty simple, and the behavior is pretty easy to observe.
This would enlarge the average read request size to 512K.
- Introduce multi-group reads and no longer wait for each group Instead of the old behavior, which submits 8 stripes and waits for them, here we would enlarge the total number of stripes to 16 * 8. Which is 8M per device, the same limit as the old scrub in-flight bios size limit.
Now every time we fill a group (8 stripes), we submit them and continue to next stripes.
Only when the full 16 * 8 stripes are all filled, we submit the remaining ones (the last group), and wait for all groups to finish. Then submit the repair writes and dev-replace writes.
This should enlarge the queue depth.
This would greatly improve the merge rate (thus read block size) and queue depth:
Before (with regression, and cached extent/csum path):
Device r/s rkB/s rrqm/s %rrqm r_await rareq-sz aqu-sz %util
nvme0n1p3 20666.00 1318240.00 10.00 0.05 0.08 63.79 1.63 100.00
After (with all patches applied):
nvme0n1p3 5165.00 2278304.00 30557.00 85.54 0.55 441.10 2.81 100.00
i.e. 1287 to 2224 MB/s.
--- fs/btrfs/scrub.c | 96 ++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 71 insertions(+), 25 deletions(-)
fs/btrfs/scrub.c +71 -25
@@ -43,9 +43,20 @@ struct scrub_ctx;/* * The following value only influences the performance. * -* This determines the batch size for stripe submitted in one go. +* This detemines how many stripes would be submitted in one go, +* which is 512KiB (BTRFS_STRIPE_LEN * SCRUB_STRIPES_PER_GROUP). */ -#define SCRUB_STRIPES_PER_SCTX 8/* That would be 8 64K stripe per-device. */ +#define SCRUB_STRIPES_PER_GROUP 8 + +/* +* How many groups we have for each sctx. +* +* This would be 8M per device, the same value as the old scrub in-flight bios +* size limit. +*/ +#define SCRUB_GROUPS_PER_SCTX 16 + +#define SCRUB_TOTAL_STRIPES (SCRUB_GROUPS_PER_SCTX * SCRUB_STRIPES_PER_GROUP)/* * The following value times PAGE_SIZE needs to be large enough to match the
@@ -172,7 +183,7 @@ struct scrub_stripe { };struct scrub_ctx { -struct scrub_stripe stripes[SCRUB_STRIPES_PER_SCTX ]; +struct scrub_stripe stripes[SCRUB_TOTAL_STRIPES ];struct scrub_stripe *raid56_data_stripes;struct btrfs_fs_info *fs_info;struct btrfs_path extent_path;
@@ -317,10 +328,10 @@ static noinline_for_stack void scrub_freif (!sctx)return ; -for (i =0 ; i <SCRUB_STRIPES_PER_SCTX ; i++) +for (i =0 ; i <SCRUB_TOTAL_STRIPES ; i++)release_scrub_stripe (&sctx->stripes[i]); -kfree (sctx); +kvfree (sctx); }static void scrub_put_ctx (struct scrub_ctx *sctx)
@@ -335,7 +346,10 @@ static noinline_for_stack struct scrub_cstruct scrub_ctx *sctx;int i; - sctx =kzalloc (sizeof (*sctx),GFP_KERNEL ); +/* Since sctx has inline 128 stripes, it can go beyond 64K easily. Use +* kvzalloc(). +*/ + sctx =kvzalloc (sizeof (*sctx),GFP_KERNEL );if (!sctx) goto nomem;refcount_set (&sctx->refs,1 );
@@ -345,7 +359,7 @@ static noinline_for_stack struct scrub_c sctx->extent_path.skip_locking =1 ; sctx->csum_path.search_commit_root =1 ; sctx->csum_path.skip_locking =1 ; -for (i =0 ; i <SCRUB_STRIPES_PER_SCTX ; i++) { +for (i =0 ; i <SCRUB_TOTAL_STRIPES ; i++) {int ret; ret =init_scrub_stripe (fs_info, &sctx->stripes[i]);
@@ -1659,6 +1673,28 @@ static bool stripe_has_metadata_error(streturn false; } +static void submit_initial_group_read (struct scrub_ctx *sctx, +unsigned int first_slot, +unsigned int nr_stripes) +{ +struct blk_plug plug; + +ASSERT (first_slot <SCRUB_TOTAL_STRIPES ); +ASSERT (first_slot + nr_stripes <=SCRUB_TOTAL_STRIPES ); + +scrub_throttle_dev_io (sctx, sctx->stripes[0 ].dev, +btrfs_stripe_nr_to_offset (nr_stripes)); +blk_start_plug (&plug); +for (int i =0 ; i < nr_stripes; i++) { +struct scrub_stripe *stripe = &sctx->stripes[first_slot + i]; + +/* Those stripes should be initialized. */ +ASSERT (test_bit (SCRUB_STRIPE_FLAG_INITIALIZED , &stripe->state)); +scrub_submit_initial_read (sctx, stripe); + } +blk_finish_plug (&plug); +} +static int flush_scrub_stripes (struct scrub_ctx *sctx) {struct btrfs_fs_info *fs_info = sctx->fs_info;
@@ -1671,11 +1707,11 @@ static int flush_scrub_stripes(struct scASSERT (test_bit (SCRUB_STRIPE_FLAG_INITIALIZED , &sctx->stripes[0 ].state)); -scrub_throttle_dev_io (sctx, sctx->stripes[0 ].dev, -btrfs_stripe_nr_to_offset (nr_stripes)); -for (int i =0 ; i < nr_stripes; i++) { - stripe = &sctx->stripes[i]; -scrub_submit_initial_read (sctx, stripe); +/* Submit the stripes which are populated but not submitted. */ +if (nr_stripes %SCRUB_STRIPES_PER_GROUP ) { +const int first_slot =round_down (nr_stripes,SCRUB_STRIPES_PER_GROUP ); + +submit_initial_group_read (sctx, first_slot, nr_stripes - first_slot); }for (int i =0 ; i < nr_stripes; i++) {
@@ -1755,21 +1791,19 @@ static void raid56_scrub_wait_endio(strustatic int queue_scrub_stripe (struct scrub_ctx *sctx,struct btrfs_block_group *bg,struct btrfs_device *dev,int mirror_num, -u64 logical,u32 length,u64 physical) +u64 logical,u32 length,u64 physical, +u64 *found_logical_ret) {struct scrub_stripe *stripe;int ret; -/* No available slot, submit all stripes and wait for them. */ -if (sctx->cur_stripe >=SCRUB_STRIPES_PER_SCTX ) { - ret =flush_scrub_stripes (sctx); -if (ret <0 ) -return ret; - } +/* +* There should always be one slot left, as caller filling the last +* slot should flush them all. +*/ +ASSERT (sctx->cur_stripe <SCRUB_TOTAL_STRIPES ); stripe = &sctx->stripes[sctx->cur_stripe]; - -/* We can queue one stripe using the remaining slot. */ scrub_reset_stripe (stripe); ret = scrub_find_fill_first_stripe(bg, &sctx->extent_path, &sctx->csum_path, dev, physical,
@@ -1777,7 +1811,20 @@ static int queue_scrub_stripe(struct scr/* Either >0 as no more extents or <0 for error. */ if (ret)return ret; +if (found_logical_ret) + *found_logical_ret = stripe->logical; sctx->cur_stripe++; + +/* We filled one group, submit it. */ +if (sctx->cur_stripe %SCRUB_STRIPES_PER_GROUP ==0 ) { +const int first_slot = sctx->cur_stripe -SCRUB_STRIPES_PER_GROUP ; + +submit_initial_group_read (sctx, first_slot,SCRUB_STRIPES_PER_GROUP ); + } + +/* Last slot used, flush them all. */ +if (sctx->cur_stripe ==SCRUB_TOTAL_STRIPES ) +return flush_scrub_stripes (sctx);return 0 ; }
@@ -1990,6 +2037,7 @@ static int scrub_simple_mirror(struct sc path.skip_locking =1 ;/* Go through each extent items inside the logical range */ while (cur_logical < logical_end) { +u64 found_logical;u64 cur_physical = physical + cur_logical - logical_start;/* Canceled? */
@@ -2014,7 +2062,7 @@ static int scrub_simple_mirror(struct sc ret =queue_scrub_stripe (sctx, bg, device, mirror_num, cur_logical, logical_end - cur_logical, - cur_physical); + cur_physical, &found_logical);if (ret >0 ) {/* No more extent, just update the accounting */ sctx->stat.last_physical = physical + logical_length;
@@ -2024,9 +2072,7 @@ static int scrub_simple_mirror(struct scif (ret <0 )break ; -ASSERT (sctx->cur_stripe >0 ); - cur_logical = sctx->stripes[sctx->cur_stripe -1 ].logical - +BTRFS_STRIPE_LEN ; + cur_logical = found_logical +BTRFS_STRIPE_LEN ;/* Don't hold CPU for too long time */ cond_resched ();
Re: [PATCH 6.5 211/285] btrfs: scrub: fix grouping of read IO
'btrfs: scrub: fix grouping of read IO' seems to intorduce a -Wmaybe-uninitialized warning (which becomes fatal with the kernel's passed -Werror=...) with 6.5.9:
``` # CC fs/btrfs/scrub.o x86_64-pc-linux-gnu-gcc -Wp,-MMD,fs/btrfs/.scrub.o.d -nostdinc -I/var/tmp/portage/sys-kernel/gentoo-kernel-6.5.9/work/linux-6.5/arch/x86/include -I./arch/x86/include/generated -I/var/tmp/portage/sys-kernel/gentoo-kernel-6.5.9/work/linux-6.5/include -I./include -I/var/tmp/portage/sys-kernel/gentoo-kernel-6.5.9/work/linux-6.5/arch/x86/include/uapi -I./arch/x86/include/generated/uapi -I/var/tmp/portage/sys-kernel/gentoo-kernel-6.5.9/work/linux-6.5/include/uapi -I./include/generated/uapi -include /var/tmp/portage/sys-kernel/gentoo-kernel-6.5.9/work/linux-6.5/include/linux/compiler-version.h -include /var/tmp/portage/sys-kernel/gentoo-kernel-6.5.9/work/linux-6.5/include/linux/kconfig.h -include /var/tmp/portage/sys-kernel/gentoo-kernel-6.5.9/work/linux-6.5/include/linux/compiler_types.h -D__KERNEL__ -Werror -fmacro-prefix-map=/var/tmp/portage/sys-kernel/gentoo-kernel-6.5.9/work/linux-6.5/= -std=gnu11 -fshort-wchar -funsigned-char -fno-common -fno-PIE -fno-strict-aliasing -Wall -Wundef -Werror=implicit-function-declaration -Werror=implicit-int -Werror=return-type -Werror=strict-prototypes -Wno-format-security -Wno-trigraphs -mno-sse -mno-mmx -mno-sse2 -mno-3dnow -mno-avx -fcf-protection=branch -fno-jump-tables -m64 -falign-jumps=1 -falign-loops=1 -mno-80387 -mno-fp-ret-in-387 -mpreferred-stack-boundary=3 -mskip-rax-setup -march=core2 -mno-red-zone -mcmodel=kernel -Wno-sign-compare -fno-asynchronous-unwind-tables -mindirect-branch=thunk-extern -mindirect-branch-register -mindirect-branch-cs-prefix -mfunction-return=thunk-extern -fno-jump-tables -mharden-sls=all -fno-delete-null-pointer-checks -Wno-frame-address -Wno-format-truncation -Wno-format-overflow -Wno-address-of-packed-member -O2 -fno-allow-store-data-races -Wframe-larger-than=2048 -fstack-protector-strong -Wno-main -Wno-unused-but-set-variable -Wno-unused-const-variable -Wno-dangling-pointer -fomit-frame-pointer -ftrivial-auto-var-init=zero -fno-stack-clash-protection -fzero-call-used-regs=used-gpr -falign-functions=16 -Wvla -Wno-pointer-sign -Wcast-function-type -fstrict-flex-arrays=3 -Wno-stringop-truncation -Wno-stringop-overflow -Wno-restrict -Wno-maybe-uninitialized -Wno-array-bounds -Wno-alloc-size-larger-than -Wimplicit-fallthrough=5 -fno-strict-overflow -fno-stack-check -fconserve-stack -Werror=date-time -Werror=incompatible-pointer-types -Werror=designated-init -Wno-packed-not-aligned -DRANDSTRUCT -fplugin=./scripts/gcc-plugins/randomize_layout_plugin.so -fplugin-arg-randomize_layout_plugin-performance-mode -fplugin=./scripts/gcc-plugins/latent_entropy_plugin.so -fplugin=./scripts/gcc-plugins/structleak_plugin.so -fplugin=./scripts/gcc-plugins/stackleak_plugin.so -DLATENT_ENTROPY_PLUGIN -DSTRUCTLEAK_PLUGIN -DSTACKLEAK_PLUGIN -fplugin-arg-stackleak_plugin-track-min-size=100 -fplugin-arg-stackleak_plugin-arch=x86 -Wextra -Wunused -Wno-unused-parameter -Wmissing-declarations -Wmissing-format-attribute -Wmissing-prototypes -Wold-style-definition -Wmissing-include-dirs -Wunused-but-set-variable -Wunused-const-variable -Wpacked-not-aligned -Wstringop-truncation -Wmaybe-uninitialized -Wno-missing-field-initializers -Wno-sign-compare -Wno-type-limits -Wno-shift-negative-value -I /var/tmp/portage/sys-kernel/gentoo-kernel-6.5.9/work/linux-6.5/fs/btrfs -I ./fs/btrfs -DKBUILD_MODFILE='"fs/btrfs/btrfs"' -DKBUILD_BASENAME='"scrub"' -DKBUILD_MODNAME='"btrfs"' -D__KBUILD_MODNAME=kmod_btrfs -c -o fs/btrfs/scrub.o /var/tmp/portage/sys-kernel/gentoo-kernel-6.5.9/work/linux-6.5/fs/btrfs/scrub.c /var/tmp/portage/sys-kernel/gentoo-kernel-6.5.9/work/linux-6.5/fs/btrfs/scrub.c: In function ‘scrub_simple_mirror.isra’: /var/tmp/portage/sys-kernel/gentoo-kernel-6.5.9/work/linux-6.5/fs/btrfs/scrub.c:2075:29: error: ‘found_logical’ may be used uninitialized [-Werror=maybe-uninitialized[https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wmaybe-uninitialized]] 2075 | cur_logical = found_logical + BTRFS_STRIPE_LEN; /var/tmp/portage/sys-kernel/gentoo-kernel-6.5.9/work/linux-6.5/fs/btrfs/scrub.c:2040:21: note: ‘found_logical’ was declared here 2040 | u64 found_logical; | ^~~~~~~~~~~~~ ```
Re: [PATCH 6.5 211/285] btrfs: scrub: fix grouping of read IO
Quoted 4 lines · Sam James
'btrfs: scrub: fix grouping of read IO' seems to intorduce a -Wmaybe-uninitialized warning (which becomes fatal with the kernel's passed -Werror=...) with 6.5.9:
Quoted 8 lines
``` /var/tmp/portage/sys-kernel/gentoo-kernel-6.5.9/work/linux-6.5/fs/btrfs/scrub.c: In function ‘scrub_simple_mirror.isra’: /var/tmp/portage/sys-kernel/gentoo-kernel-6.5.9/work/linux-6.5/fs/btrfs/scrub.c:2075:29: error: ‘found_logical’ may be used uninitialized [-Werror=maybe-uninitialized[https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wmaybe-uninitialized]] 2075 | cur_logical = found_logical + BTRFS_STRIPE_LEN; /var/tmp/portage/sys-kernel/gentoo-kernel-6.5.9/work/linux-6.5/fs/btrfs/scrub.c:2040:21: note: ‘found_logical’ was declared here 2040 | u64 found_logical; | ^~~~~~~~~~~~~ ```
Good find! found_logical is passed by reference to queue_scrub_stripe(..) (inlined) where it is used without ever being set:
...
/* Either >0 as no more extents or <0 for error. */ if (ret) return ret; if (found_logical_ret) *found_logical_ret = stripe->logical; sctx->cur_stripe++;
...
Something is missing here, and somehow I don't think it's just the top-level initialisation of found_logical.
-h
Re: [PATCH 6.5 211/285] btrfs: scrub: fix grouping of read IO
Quoted 26 lines · Holger Hoffstätte
Quoted 4 lines · Sam James
'btrfs: scrub: fix grouping of read IO' seems to intorduce a -Wmaybe-uninitialized warning (which becomes fatal with the kernel's passed -Werror=...) with 6.5.9:
Quoted 8 lines
``` /var/tmp/portage/sys-kernel/gentoo-kernel-6.5.9/work/linux-6.5/fs/btrfs/scrub.c: In function ‘scrub_simple_mirror.isra’: /var/tmp/portage/sys-kernel/gentoo-kernel-6.5.9/work/linux-6.5/fs/btrfs/scrub.c:2075:29: error: ‘found_logical’ may be used uninitialized [-Werror=maybe-uninitialized[https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wmaybe-uninitialized]] 2075 | cur_logical = found_logical + BTRFS_STRIPE_LEN; /var/tmp/portage/sys-kernel/gentoo-kernel-6.5.9/work/linux-6.5/fs/btrfs/scrub.c:2040:21: note: ‘found_logical’ was declared here 2040 | u64 found_logical; | ^~~~~~~~~~~~~ ```Good find!
found_logicalis passed by reference toqueue_scrub_stripe(..)(inlined) where it is used without ever being set:...
/* Either >0 as no more extents or <0 for error. */ if (ret)
return ret;
if (found_logical_ret)
*found_logical_ret=stripe->logical; sctx->cur_stripe++;
...
Quoted 2 lines
Something is missing here, and somehow I don't think it's just the top-level initialisation of
found_logical.
This looks like a false alert for me.
@found_logical is intentionally uninitialized to catch any uninitialized usage by compiler.
It would be set by queue_scrub_stripe() when there is any stripe found.
If there is no stripe found, queue_scrub_stripe() would return >0, then we know there is no more extent and break the loop. If there is any error, we error out too, thus no problem with that.
So to me this looks like a false alert.
Mind to share the compiler and its version?
Thanks,
Qu
Quoted 2 lines
-h
Re: [PATCH 6.5 211/285] btrfs: scrub: fix grouping of read IO
Quoted 31 lines · Qu Wenruo
Quoted 15 lines · Holger Hoffstätte
Quoted 4 lines · Sam James
'btrfs: scrub: fix grouping of read IO' seems to intorduce a -Wmaybe-uninitialized warning (which becomes fatal with the kernel's passed -Werror=...) with 6.5.9:
Quoted 10 lines
``` /var/tmp/portage/sys-kernel/gentoo-kernel-6.5.9/work/linux-6.5/fs/btrfs/scrub.c: In function ‘scrub_simple_mirror.isra’: /var/tmp/portage/sys-kernel/gentoo-kernel-6.5.9/work/linux-6.5/fs/btrfs/scrub.c:2075:29: error: ‘found_logical’ may be used uninitialized [-Werror=maybe-uninitialized[https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wmaybe-uninitialized]] 2075 | cur_logical = found_logical + BTRFS_STRIPE_LEN; /var/tmp/portage/sys-kernel/gentoo-kernel-6.5.9/work/linux-6.5/fs/btrfs/scrub.c:2040:21: note: ‘found_logical’ was declared here 2040 | u64 found_logical; | ^~~~~~~~~~~~~ ```Quoted 14 lines
Good find!
found_logicalis passed by reference toqueue_scrub_stripe(..)(inlined)
where it is used without ever being set:
...
/* Either >0 as no more extents or <0 for error. */ if (ret)
return ret;
if (found_logical_ret)
*found_logical_ret=stripe->logical; sctx->cur_stripe++;
...
Something is missing here, and somehow I don't think it's just the top-level
initialisation offound_logical.
Quoted 5 lines
This looks like a false alert for me.
@found_logical is intentionally uninitialized to catch any uninitialized usage by compiler.
I feel like this sort of thing is going to be inevitable with -Wmaybe-uninitialized.
Quoted 10 lines
It would be set by
queue_scrub_stripe()when there is any stripe found.If there is no stripe found,
queue_scrub_stripe()would return >0, then we know there is no more extent and break the loop. If there is any error, we error out too, thus no problem with that.So to me this looks like a false alert.
Mind to share the compiler and its version?
Sure, GCC 14.0.0 20231022 (experimental). Sorry, I'd meant to include that in the original post..
Quoted 3 lines
Thanks,
QuQuoted 1 line
-h
Re: [PATCH 6.5 211/285] btrfs: scrub: fix grouping of read IO
Quoted 34 lines · Sam James
Quoted 31 lines · Qu Wenruo
Quoted 29 lines · Holger Hoffstätte
Quoted 4 lines · Sam James
'btrfs: scrub: fix grouping of read IO' seems to intorduce a -Wmaybe-uninitialized warning (which becomes fatal with the kernel's passed -Werror=...) with 6.5.9:
Quoted 10 lines
``` /var/tmp/portage/sys-kernel/gentoo-kernel-6.5.9/work/linux-6.5/fs/btrfs/scrub.c: In function ‘scrub_simple_mirror.isra’: /var/tmp/portage/sys-kernel/gentoo-kernel-6.5.9/work/linux-6.5/fs/btrfs/scrub.c:2075:29: error: ‘found_logical’ may be used uninitialized [-Werror=maybe-uninitialized[https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wmaybe-uninitialized]] 2075 | cur_logical = found_logical + BTRFS_STRIPE_LEN; /var/tmp/portage/sys-kernel/gentoo-kernel-6.5.9/work/linux-6.5/fs/btrfs/scrub.c:2040:21: note: ‘found_logical’ was declared here 2040 | u64 found_logical; | ^~~~~~~~~~~~~ ```Good find!
found_logicalis passed by reference toqueue_scrub_stripe(..)(inlined)
where it is used without ever being set:
...
/* Either >0 as no more extents or <0 for error. */ if (ret)
return ret;
if (found_logical_ret)
*found_logical_ret=stripe->logical; sctx->cur_stripe++;
...
Something is missing here, and somehow I don't think it's just the top-level
initialisation offound_logical.
Quoted 7 lines
Quoted 5 lines
This looks like a false alert for me.
@found_logical is intentionally uninitialized to catch any uninitialized usage by compiler.
I feel like this sort of thing is going to be inevitable with -Wmaybe-uninitialized.
Indeed, it can be tricky for compilers to handle.
But it's not that frequent, thus the btrfs community is mostly fine to handle those reports manually.
Quoted 7 lines
Quoted 7 lines
It would be set by
queue_scrub_stripe()when there is any stripe found.If there is no stripe found,
queue_scrub_stripe()would return >0, then we know there is no more extent and break the loop. If there is any error, we error out too, thus no problem with that.
Quoted 7 lines
Quoted 4 lines
So to me this looks like a false alert.
Mind to share the compiler and its version?
Sure, GCC 14.0.0 20231022 (experimental). Sorry, I'd meant to include that in the original post..
Wow, the first time I can not catch up on the toolchain version...
And considering it's still experimental, I'd say if we got another report on this particular call site, we may consider add a fix for it, by simply initializing @found_logical to zero.
Thanks,
Qu
Quoted 5 lines
Quoted 4 lines
Thanks,
QuQuoted 1 line
-h
Re: [PATCH 6.5 211/285] btrfs: scrub: fix grouping of read IO
In reply to Qu WenruoQuoted 29 lines · Qu Wenruo
Quoted 26 lines · Holger Hoffstätte
Quoted 4 lines · Sam James
'btrfs: scrub: fix grouping of read IO' seems to intorduce a -Wmaybe-uninitialized warning (which becomes fatal with the kernel's passed -Werror=...) with 6.5.9:
Quoted 8 lines
``` /var/tmp/portage/sys-kernel/gentoo-kernel-6.5.9/work/linux-6.5/fs/btrfs/scrub.c: In function ‘scrub_simple_mirror.isra’: /var/tmp/portage/sys-kernel/gentoo-kernel-6.5.9/work/linux-6.5/fs/btrfs/scrub.c:2075:29: error: ‘found_logical’ may be used uninitialized [-Werror=maybe-uninitialized[https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wmaybe-uninitialized]] 2075 | cur_logical = found_logical + BTRFS_STRIPE_LEN; /var/tmp/portage/sys-kernel/gentoo-kernel-6.5.9/work/linux-6.5/fs/btrfs/scrub.c:2040:21: note: ‘found_logical’ was declared here 2040 | u64 found_logical; | ^~~~~~~~~~~~~ ```Good find!
found_logicalis passed by reference toqueue_scrub_stripe(..)(inlined) where it is used without ever being set:...
/* Either >0 as no more extents or <0 for error. */ if (ret)
return ret;
if (found_logical_ret)
*found_logical_ret=stripe->logical; sctx->cur_stripe++;
...
Quoted 8 lines
Quoted 2 lines
Something is missing here, and somehow I don't think it's just the top-level initialisation of
found_logical.This looks like a false alert for me.
@found_logical is intentionally uninitialized to catch any uninitialized usage by compiler.
It would be set by
queue_scrub_stripe()when there is any stripe found.
Can you show me where the reference is set before the quoted if block? The warning happens because according to the compiler this is exactly not what's happening, and I did not see any initializing write either.
thanks,
Holger
Re: [PATCH 6.5 211/285] btrfs: scrub: fix grouping of read IO
Quoted 36 lines · Holger Hoffstätte
Quoted 35 lines · Qu Wenruo
Quoted 31 lines · Holger Hoffstätte
Quoted 4 lines · Sam James
'btrfs: scrub: fix grouping of read IO' seems to intorduce a -Wmaybe-uninitialized warning (which becomes fatal with the kernel's passed -Werror=...) with 6.5.9:
Quoted 9 lines
``` /var/tmp/portage/sys-kernel/gentoo-kernel-6.5.9/work/linux-6.5/fs/btrfs/scrub.c: In function ‘scrub_simple_mirror.isra’: /var/tmp/portage/sys-kernel/gentoo-kernel-6.5.9/work/linux-6.5/fs/btrfs/scrub.c:2075:29: error: ‘found_logical’ may be used uninitialized [-Werror=maybe-uninitialized[https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wmaybe-uninitialized]] 2075 | cur_logical = found_logical + BTRFS_STRIPE_LEN; /var/tmp/portage/sys-kernel/gentoo-kernel-6.5.9/work/linux-6.5/fs/btrfs/scrub.c:2040:21: note: ‘found_logical’ was declared here 2040 | u64 found_logical; | ^~~~~~~~~~~~~ ```Good find!
found_logicalis passed by reference toqueue_scrub_stripe(..)(inlined)
where it is used without ever being set:...
/* Either >0 as no more extents or <0 for error. */ if (ret)
return ret;
if (found_logical_ret)
*found_logical_ret=stripe->logical; sctx->cur_stripe++;
...Something is missing here, and somehow I don't think it's just the top-level
initialisation offound_logical.
Quoted 8 lines
Quoted 6 lines
This looks like a false alert for me.
@found_logical is intentionally uninitialized to catch any uninitialized usage by compiler.
It would be set by
queue_scrub_stripe()when there is any stripe found.Can you show me where the reference is set before the quoted if block?
Sure.
Firstly inside queue_scrub_stripe():
```
ret = scrub_find_fill_first_stripe(bg, &sctx->extent_path,
&sctx->csum_path, dev, physical,
mirror_num, logical, length,
stripe);
/* Either >0 as no more extents or <0 for error. */
if (ret)
return ret;
if (found_logical_ret)
*found_logical_ret = stripe->logical;
```In this case, we would only set @found_logical_ret to the found stripe's logical.
Either we got ret > 0, meaning no more extent in the chunk, or we got some critical error.
Then back to scrub_simple_mirrors():
```
ret = queue_scrub_stripe(sctx, bg, device, mirror_num,
cur_logical, logical_end -
cur_logical,
cur_physical, &found_logical);
if (ret > 0) {
/* No more extent, just update the accounting */
sctx->stat.last_physical = physical +
logical_length;
ret = 0;
break;
}
if (ret < 0)
break;
cur_logical = found_logical + BTRFS_STRIPE_LEN;
```We got to the if block I mentioned.
Either we got ret != 0, then we would break out the whole loop of scrub_simple_mirror().
Or we got ret == 0, which would initialize @found_logical.
Thanks,
Qu
Quoted 6 lines
The warning happens because according to the compiler this is exactly not what's
happening, and I did not see any initializing write either.thanks,
Holger
Re: [PATCH 6.5 211/285] btrfs: scrub: fix grouping of read IO
Quoted 65 lines · Qu Wenruo
Quoted 36 lines · Holger Hoffstätte
Quoted 35 lines · Qu Wenruo
Quoted 31 lines · Holger Hoffstätte
Quoted 4 lines · Sam James
'btrfs: scrub: fix grouping of read IO' seems to intorduce a -Wmaybe-uninitialized warning (which becomes fatal with the kernel's passed -Werror=...) with 6.5.9:
Quoted 9 lines
``` /var/tmp/portage/sys-kernel/gentoo-kernel-6.5.9/work/linux-6.5/fs/btrfs/scrub.c: In function ‘scrub_simple_mirror.isra’: /var/tmp/portage/sys-kernel/gentoo-kernel-6.5.9/work/linux-6.5/fs/btrfs/scrub.c:2075:29: error: ‘found_logical’ may be used uninitialized [-Werror=maybe-uninitialized[https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wmaybe-uninitialized]] 2075 | cur_logical = found_logical + BTRFS_STRIPE_LEN; /var/tmp/portage/sys-kernel/gentoo-kernel-6.5.9/work/linux-6.5/fs/btrfs/scrub.c:2040:21: note: ‘found_logical’ was declared here 2040 | u64 found_logical; | ^~~~~~~~~~~~~ ```Good find!
found_logicalis passed by reference toqueue_scrub_stripe(..)(inlined)
where it is used without ever being set:...
/* Either >0 as no more extents or <0 for error. */ if (ret)
return ret;
if (found_logical_ret)
*found_logical_ret=stripe->logical; sctx->cur_stripe++;
...Something is missing here, and somehow I don't think it's just the top-level
initialisation offound_logical.Quoted 8 lines
Quoted 6 lines
This looks like a false alert for me.
@found_logical is intentionally uninitialized to catch any uninitialized usage by compiler.
It would be set by
queue_scrub_stripe()when there is any stripe found.Can you show me where the reference is set before the quoted if block?
Sure.
Firstly inside
queue_scrub_stripe():``` ret = scrub_find_fill_first_stripe(bg, &sctx->extent_path, &sctx->csum_path, dev, physical, mirror_num, logical, length, stripe); /* Either >0 as no more extents or <0 for error. */ if (ret) return ret; if (found_logical_ret) *found_logical_ret = stripe->logical; ```
Quoted 5 lines
In this case, we would only set @found_logical_ret to the found stripe's logical.
Either we got ret > 0, meaning no more extent in the chunk, or we got some critical error.
Sorry, missing the latter part of the sentence:
In either case, the caller would handle it.
Quoted 37 lines
Then back to
scrub_simple_mirrors():``` ret = queue_scrub_stripe(sctx, bg, device, mirror_num, cur_logical, logical_end - cur_logical, cur_physical, &found_logical); if (ret > 0) { /* No more extent, just update the accounting */ sctx->stat.last_physical = physical + logical_length; ret = 0; break; } if (ret < 0) break; cur_logical = found_logical + BTRFS_STRIPE_LEN; ```We got to the if block I mentioned.
Either we got ret != 0, then we would break out the whole loop of
scrub_simple_mirror().
Or we got ret == 0, which would initialize @found_logical.Thanks,
QuQuoted 6 lines
The warning happens because according to the compiler this is exactly not what's
happening, and I did not see any initializing write either.thanks,
Holger
Re: [PATCH 6.5 211/285] btrfs: scrub: fix grouping of read IO
In reply to Qu WenruoQuoted 64 lines · Qu Wenruo
Quoted 36 lines · Holger Hoffstätte
Quoted 35 lines · Qu Wenruo
Quoted 31 lines · Holger Hoffstätte
Quoted 4 lines · Sam James
'btrfs: scrub: fix grouping of read IO' seems to intorduce a -Wmaybe-uninitialized warning (which becomes fatal with the kernel's passed -Werror=...) with 6.5.9:
Quoted 9 lines
``` /var/tmp/portage/sys-kernel/gentoo-kernel-6.5.9/work/linux-6.5/fs/btrfs/scrub.c: In function ‘scrub_simple_mirror.isra’: /var/tmp/portage/sys-kernel/gentoo-kernel-6.5.9/work/linux-6.5/fs/btrfs/scrub.c:2075:29: error: ‘found_logical’ may be used uninitialized [-Werror=maybe-uninitialized[https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wmaybe-uninitialized]] 2075 | cur_logical = found_logical + BTRFS_STRIPE_LEN; /var/tmp/portage/sys-kernel/gentoo-kernel-6.5.9/work/linux-6.5/fs/btrfs/scrub.c:2040:21: note: ‘found_logical’ was declared here 2040 | u64 found_logical; | ^~~~~~~~~~~~~ ```Good find!
found_logicalis passed by reference toqueue_scrub_stripe(..)(inlined)
where it is used without ever being set:...
/* Either >0 as no more extents or <0 for error. */ if (ret)
return ret;
if (found_logical_ret)
*found_logical_ret=stripe->logical; sctx->cur_stripe++;
...Something is missing here, and somehow I don't think it's just the top-level
initialisation offound_logical.Quoted 8 lines
Quoted 6 lines
This looks like a false alert for me.
@found_logical is intentionally uninitialized to catch any uninitialized usage by compiler.
It would be set by
queue_scrub_stripe()when there is any stripe found.Can you show me where the reference is set before the quoted if block?
Sure.
Firstly inside
queue_scrub_stripe():``` ret = scrub_find_fill_first_stripe(bg, &sctx->extent_path, &sctx->csum_path, dev, physical, mirror_num, logical, length, stripe); /* Either >0 as no more extents or <0 for error. */ if (ret) return ret; if (found_logical_ret) *found_logical_ret = stripe->logical; ```
Quoted 7 lines
In this case, we would only set @found_logical_ret to the found stripe's logical.
Either we got ret > 0, meaning no more extent in the chunk, or we got some critical error.
Then back to
scrub_simple_mirrors():
I think I now understand the comment. This is a terrible foot gun, and in fact shows that this is not a false alert at all.
Within queue_scrub_stripe() you are "possibly" using (checking) a reference that has not been initialized, neither in the caller nor within queue_scrub_stripe(). To the compiler this reference may not exist yet (even if we know that it is on the stack..) and point to la-la land. The fact that the logic depends on ret always being != 0 is not visible to the compiler, so the warning is completely
correct: 0 is a valid possible value for ret, so this potentially allows the uninitialized read to happen.
What happens after that is not the point. You cannot safely check an uninitialized reference, even when the control flow "cannot happen" due to a data dependency.
It seems to me the safest way forward is to simply initialize found_logical in the parent and remove the "if (found_logical_ret)" check, since it does nothing useful. Would that work?
thanks,
Holger
Re: [PATCH 6.5 211/285] btrfs: scrub: fix grouping of read IO
Quoted 84 lines · Holger Hoffstätte
Quoted 64 lines · Qu Wenruo
Quoted 36 lines · Holger Hoffstätte
Quoted 35 lines · Qu Wenruo
Quoted 31 lines · Holger Hoffstätte
Quoted 4 lines · Sam James
'btrfs: scrub: fix grouping of read IO' seems to intorduce a -Wmaybe-uninitialized warning (which becomes fatal with the kernel's passed -Werror=...) with 6.5.9:
Quoted 9 lines
``` /var/tmp/portage/sys-kernel/gentoo-kernel-6.5.9/work/linux-6.5/fs/btrfs/scrub.c: In function ‘scrub_simple_mirror.isra’: /var/tmp/portage/sys-kernel/gentoo-kernel-6.5.9/work/linux-6.5/fs/btrfs/scrub.c:2075:29: error: ‘found_logical’ may be used uninitialized [-Werror=maybe-uninitialized[https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html#index-Wmaybe-uninitialized]] 2075 | cur_logical = found_logical + BTRFS_STRIPE_LEN; /var/tmp/portage/sys-kernel/gentoo-kernel-6.5.9/work/linux-6.5/fs/btrfs/scrub.c:2040:21: note: ‘found_logical’ was declared here 2040 | u64 found_logical; | ^~~~~~~~~~~~~ ```Good find!
found_logicalis passed by reference toqueue_scrub_stripe(..)(inlined)
where it is used without ever being set:...
/* Either >0 as no more extents or <0 for error. */ if (ret)
return ret;
if (found_logical_ret)
*found_logical_ret=stripe->logical; sctx->cur_stripe++;
...Something is missing here, and somehow I don't think it's just the top-level
initialisation offound_logical.Quoted 8 lines
Quoted 6 lines
This looks like a false alert for me.
@found_logical is intentionally uninitialized to catch any uninitialized usage by compiler.
It would be set by
queue_scrub_stripe()when there is any stripe found.Can you show me where the reference is set before the quoted if block?
Sure.
Firstly inside
queue_scrub_stripe():``` ret = scrub_find_fill_first_stripe(bg, &sctx->extent_path, &sctx->csum_path, dev, physical, mirror_num, logical, length, stripe); /* Either >0 as no more extents or <0 for error. */ if (ret) return ret; if (found_logical_ret) *found_logical_ret = stripe->logical; ```Quoted 7 lines
In this case, we would only set @found_logical_ret to the found stripe's logical.
Either we got ret > 0, meaning no more extent in the chunk, or we got some critical error.
Then back to
scrub_simple_mirrors():I think I now understand the comment. This is a terrible foot gun, and in fact shows that this is not a false alert at all.
Within
queue_scrub_stripe()you are "possibly" using (checking) a reference that has not been initialized, neither in the caller nor withinqueue_scrub_stripe(). To the compiler this reference may not exist yet (even if we know that it is on the stack..) and point to la-la land. The fact that the logic depends on ret always being != 0 is not visible to the compiler, so the warning is completely
correct: 0 is a valid possible value for ret, so this potentially allows the uninitialized read to happen.
Quoted 7 lines
What happens after that is not the point. You cannot safely check an uninitialized reference, even when the control flow "cannot happen" due to a data dependency.
It seems to me the safest way forward is to simply initialize
found_logicalin the parent and remove the "if (found_logical_ret)" check, since it does nothing useful. Would that work?
Sure, that sounds pretty reasonable.
The "if (found_logical_ret)" is totally duplicated, if following the regular btrfs way, I'd convert it to an "ASSERT(found_logical_ret);" at the beginning of the function queue_scrub_stripe().
In that case, I'm totally fine to submit a patch to fix this warning.
Thanks for the report,
Qu
Quoted 2 lines
thanks,
Holger
Greg Kroah-Hartman
maintainerPATCH 212/285 drm/mxsfb: Disable overlay plane in mxsfb_plane_overlay_atomic_disable()
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Liu Ying <[email protected]>
commit aa656d48e871a1b062e1bbf9474d8b831c35074c upstream.
When disabling overlay plane in mxsfb_plane_overlay_atomic_update(), overlay plane's framebuffer pointer is NULL. So, dereferencing it would cause a kernel Oops(NULL pointer dereferencing). Fix the issue by disabling overlay plane in mxsfb_plane_overlay_atomic_disable() instead.
--- drivers/gpu/drm/mxsfb/mxsfb_kms.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/gpu/drm/mxsfb/mxsfb_kms.c +9 -0
@@ -611,6 +611,14 @@ static void mxsfb_plane_overlay_atomic_uwritel (ctrl, mxsfb->base +LCDC_AS_CTRL ); } +static void mxsfb_plane_overlay_atomic_disable (struct drm_plane *plane, +struct drm_atomic_state *state) +{ +struct mxsfb_drm_private *mxsfb =to_mxsfb_drm_private (plane->dev); + +writel (0 , mxsfb->base +LCDC_AS_CTRL ); +} +static bool mxsfb_format_mod_supported (struct drm_plane *plane,uint32_t format,uint64_t modifier)
@@ -626,6 +634,7 @@ static const struct drm_plane_helper_funstatic const struct drm_plane_helper_funcs mxsfb_plane_overlay_helper_funcs = { .atomic_check = mxsfb_plane_atomic_check, .atomic_update = mxsfb_plane_overlay_atomic_update, + .atomic_disable = mxsfb_plane_overlay_atomic_disable, };static const struct drm_plane_funcs mxsfb_plane_funcs = {
Greg Kroah-Hartman
maintainerPATCH 213/285 mtd: rawnand: brcmnand: Fix crash during the panic_write
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: William Zhang <[email protected]>
commit e66dd317194daae0475fe9e5577c80aa97f16cb9 upstream.
When executing a NAND command within the panic write path, wait for any pending command instead of calling BUG_ON to avoid crashing while already crashing.
--- drivers/mtd/nand/raw/brcmnand/brcmnand.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
drivers/mtd/nand/raw/brcmnand/brcmnand.c +11 -1
@@ -1592,7 +1592,17 @@ static void brcmnand_send_cmd(struct brcdev_dbg (ctrl->dev,"send native cmd %d addr 0x%llx\n" , cmd, cmd_addr); -BUG_ON (ctrl->cmd_pending !=0 ); +/* +* If we came here through _panic_write and there is a pending +* command, try to wait for it. If it times out, rather than +* hitting BUG_ON, just return so we don't crash while crashing. +*/ +if (oops_in_progress) { +if (ctrl->cmd_pending && +bcmnand_ctrl_poll_status (ctrl,NAND_CTRL_RDY ,NAND_CTRL_RDY ,0 )) +return ; + }else +BUG_ON (ctrl->cmd_pending !=0 ); ctrl->cmd_pending = cmd; ret =bcmnand_ctrl_poll_status (ctrl,NAND_CTRL_RDY ,NAND_CTRL_RDY ,0 );
Greg Kroah-Hartman
maintainerPATCH 214/285 mtd: rawnand: brcmnand: Fix potential out-of-bounds access in oob write
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: William Zhang <[email protected]>
commit 5d53244186c9ac58cb88d76a0958ca55b83a15cd upstream.
When the oob buffer length is not in multiple of words, the oob write function does out-of-bounds read on the oob source buffer at the last iteration. Fix that by always checking length limit on the oob buffer read and fill with 0xff when reaching the end of the buffer to the oob registers.
--- drivers/mtd/nand/raw/brcmnand/brcmnand.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-)
drivers/mtd/nand/raw/brcmnand/brcmnand.c +16 -2
@@ -1461,19 +1461,33 @@ static int write_oob_to_regs(struct brcm const u8 *oob, int sas, int sector_1k) { int tbytes = sas << sector_1k; -int j; +int j, k =0 ; +u32 last =0xffffffff ; +u8 *plast = (u8 *)&last;/* Adjust OOB values for 1K sector size */ if (sector_1k && (i &0x01 )) tbytes =max (0 , tbytes - (int )ctrl->max_oob); tbytes =min_t (int, tbytes, ctrl->max_oob); -for (j =0 ; j < tbytes; j +=4 ) +/* +* tbytes may not be multiple of words. Make sure we don't read out of +* the boundary and stop at last word. +*/ +for (j =0 ; (j +3 ) < tbytes; j +=4 )oob_reg_write (ctrl, j, (oob[j +0 ] <<24 ) | (oob[j +1 ] <<16 ) | (oob[j +2 ] <<8 ) | (oob[j +3 ] <<0 )); + +/* handle the remaing bytes */ +while (j < tbytes) + plast[k++] = oob[j++]; + +if (tbytes &0x3 ) +oob_reg_write (ctrl, (tbytes & ~0x3 ), (__force u32 )cpu_to_be32 (last)); +return tbytes; }
Greg Kroah-Hartman
maintainerPATCH 215/285 mtd: spi-nor: Correct flags for Winbond w25q128
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linus Walleij <[email protected]>
commit 83e824a4a595132f9bd7ac4f5afff857bfc5991e upstream.
The Winbond "w25q128" (actual vendor name W25Q128JV) has exactly the same flags as the sibling device "w25q128jv". The devices both require unlocking to enable write access.
The actual product naming between devices vs the Linux strings in winbond.c:
0xef4018: "w25q128" W25Q128JV-IN/IQ/JQ0xef7018: "w25q128jv" W25Q128JV-IM/JM
The latter device, "w25q128jv" supports features named DTQ and QPI, otherwise it is the same.
Not having the right flags has the annoying side effect that write access does not work.
After this patch I can write to the flash on the Inteno XG6846 router.
The flash memory also supports dual and quad SPI modes. This does not currently manifest, but by turning on SFDP parsing, the right SPI modes are emitted in /sys/kernel/debug/spi-nor/spi1.0/capabilities for this chip, so we also turn on this.
Since we now have determined that SFDP parsing works on the device, we also detect the geometry using SFDP.
After this dmesg and sysfs says:
[ 1.062401] spi-nor spi1.0: w25q128 (16384 Kbytes)
cat erasesize
65536
(16384*1024)/65536 = 256 sectors
spi-nor sysfs:
cat jedec_id
ef4018
cat manufacturer
winbond
cat partname
w25q128
hexdump -v -C sfdp
00000000 53 46 44 50 05 01 00 ff 00 05 01 10 80 00 00 ff 00000010 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 00000020 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 00000030 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 00000040 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 00000050 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 00000060 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 00000070 ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff ff 00000080 e5 20 f9 ff ff ff ff 07 44 eb 08 6b 08 3b 42 bb 00000090 fe ff ff ff ff ff 00 00 ff ff 40 eb 0c 20 0f 52 000000a0 10 d8 00 00 36 02 a6 00 82 ea 14 c9 e9 63 76 33 000000b0 7a 75 7a 75 f7 a2 d5 5c 19 f7 4d ff e9 30 f8 80
--- drivers/mtd/spi-nor/winbond.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/mtd/spi-nor/winbond.c +3 -2
@@ -120,8 +120,9 @@ static const struct flash_info winbond_n NO_SFDP_FLAGS(SECT_4K) }, { "w25q80bl", INFO(0xef4014, 0, 64 * 1024, 16) NO_SFDP_FLAGS(SECT_4K) }, - { "w25q128", INFO(0xef4018, 0, 64 * 1024, 256) - NO_SFDP_FLAGS(SECT_4K) }, + { "w25q128", INFO(0xef4018, 0, 0, 0) + PARSE_SFDP + FLAGS(SPI_NOR_HAS_LOCK | SPI_NOR_HAS_TB) }, { "w25q256", INFO(0xef4019, 0, 64 * 1024, 512) NO_SFDP_FLAGS(SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) .fixups = &w25q256_fixups },
Greg Kroah-Hartman
maintainerPATCH 216/285 mtd: rawnand: brcmnand: Fix potential false time out warning
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: William Zhang <[email protected]>
commit 9cc0a598b944816f2968baf2631757f22721b996 upstream.
If system is busy during the command status polling function, the driver may not get the chance to poll the status register till the end of time out and return the premature status. Do a final check after time out happens to ensure reading the correct status.
--- drivers/mtd/nand/raw/brcmnand/brcmnand.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/mtd/nand/raw/brcmnand/brcmnand.c +8 -0
@@ -1072,6 +1072,14 @@ static int bcmnand_ctrl_poll_status(strucpu_relax (); }while (time_after (limit, jiffies)); +/* +* do a final check after time out in case the CPU was busy and the driver +* did not get enough time to perform the polling to avoid false alarms +*/ + val =brcmnand_read_reg (ctrl,BRCMNAND_INTFC_STATUS ); +if ((val & mask) == expected_val) +return 0 ; +dev_warn (ctrl->dev,"timeout on status poll (expected %x got %x)\n" , expected_val, val & mask);
Greg Kroah-Hartman
maintainerPATCH 217/285 mtd: rawnand: brcmnand: Fix ECC level field setting for v7.2 controller
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: William Zhang <[email protected]>
commit 2ec2839a9062db8a592525a3fdabd42dcd9a3a9b upstream.
v7.2 controller has different ECC level field size and shift in the acc control register than its predecessor and successor controller. It needs to be set specifically.
--- drivers/mtd/nand/raw/brcmnand/brcmnand.c | 74 +++++++++++++++++-------------- 1 file changed, 41 insertions(+), 33 deletions(-)
drivers/mtd/nand/raw/brcmnand/brcmnand.c +41 -33
@@ -272,6 +272,7 @@ struct brcmnand_controller {const unsigned int *page_sizes;unsigned int page_size_shift;unsigned int max_oob; +u32 ecc_level_shift;u32 features;/* for low-power standby/resume only */
@@ -596,6 +597,34 @@ enum { INTFC_CTLR_READY = BIT(31), }; +/*********************************************************************** +* NAND ACC CONTROL bitfield +* +* Some bits have remained constant throughout hardware revision, while +* others have shifted around. +***********************************************************************/ + +/* Constant for all versions (where supported) */ +enum { +/* See BRCMNAND_HAS_CACHE_MODE */ +ACC_CONTROL_CACHE_MODE =BIT (22 ), + +/* See BRCMNAND_HAS_PREFETCH */ +ACC_CONTROL_PREFETCH =BIT (23 ), + +ACC_CONTROL_PAGE_HIT =BIT (24 ), +ACC_CONTROL_WR_PREEMPT =BIT (25 ), +ACC_CONTROL_PARTIAL_PAGE =BIT (26 ), +ACC_CONTROL_RD_ERASED =BIT (27 ), +ACC_CONTROL_FAST_PGM_RDIN =BIT (28 ), +ACC_CONTROL_WR_ECC =BIT (30 ), +ACC_CONTROL_RD_ECC =BIT (31 ), +}; + +#define ACC_CONTROL_ECC_SHIFT 16 +/* Only for v7.2 */ +#define ACC_CONTROL_ECC_EXT_SHIFT 13 +static inline bool brcmnand_non_mmio_ops (struct brcmnand_controller *ctrl) {#if IS_ENABLED (CONFIG_MTD_NAND_BRCMNAND_BCMA )
@@ -737,6 +766,12 @@ static int brcmnand_revision_init(structelse if (of_property_read_bool (ctrl->dev->of_node,"brcm,nand-has-wp" )) ctrl->features |=BRCMNAND_HAS_WP ; +/* v7.2 has different ecc level shift in the acc register */ +if (ctrl->nand_version ==0x0702 ) + ctrl->ecc_level_shift =ACC_CONTROL_ECC_EXT_SHIFT ; +else + ctrl->ecc_level_shift =ACC_CONTROL_ECC_SHIFT ; +return 0 ; }
@@ -931,30 +966,6 @@ static inline int brcmnand_cmd_shift(strreturn 0 ; } -/*********************************************************************** -* NAND ACC CONTROL bitfield -* -* Some bits have remained constant throughout hardware revision, while -* others have shifted around. -***********************************************************************/ - -/* Constant for all versions (where supported) */ -enum { -/* See BRCMNAND_HAS_CACHE_MODE */ -ACC_CONTROL_CACHE_MODE =BIT (22 ), - -/* See BRCMNAND_HAS_PREFETCH */ -ACC_CONTROL_PREFETCH =BIT (23 ), - -ACC_CONTROL_PAGE_HIT =BIT (24 ), -ACC_CONTROL_WR_PREEMPT =BIT (25 ), -ACC_CONTROL_PARTIAL_PAGE =BIT (26 ), -ACC_CONTROL_RD_ERASED =BIT (27 ), -ACC_CONTROL_FAST_PGM_RDIN =BIT (28 ), -ACC_CONTROL_WR_ECC =BIT (30 ), -ACC_CONTROL_RD_ECC =BIT (31 ), -}; -static inline u32 brcmnand_spare_area_mask (struct brcmnand_controller *ctrl) {if (ctrl->nand_version ==0x0702 )
@@ -967,18 +978,15 @@ static inline u32 brcmnand_spare_area_mareturn GENMASK (4 ,0 ); } -#define NAND_ACC_CONTROL_ECC_SHIFT 16 -#define NAND_ACC_CONTROL_ECC_EXT_SHIFT 13 -static inline u32 brcmnand_ecc_level_mask (struct brcmnand_controller *ctrl) {u32 mask = (ctrl->nand_version >=0x0600 ) ?0x1f :0x0f ; - mask <<=NAND_ACC_CONTROL_ECC_SHIFT ; + mask <<=ACC_CONTROL_ECC_SHIFT ;/* v7.2 includes additional ECC levels */ -if (ctrl->nand_version >=0x0702 ) - mask |=0x7 <<NAND_ACC_CONTROL_ECC_EXT_SHIFT ; +if (ctrl->nand_version ==0x0702 ) + mask |=0x7 <<ACC_CONTROL_ECC_EXT_SHIFT ;return mask; }
@@ -992,8 +1000,8 @@ static void brcmnand_set_ecc_enabled(strif (en) { acc_control |= ecc_flags;/* enable RD/WR ECC */ - acc_control |= host->hwcfg.ecc_level - <<NAND_ACC_CONTROL_ECC_SHIFT ; + acc_control &= ~brcmnand_ecc_level_mask (ctrl); + acc_control |= host->hwcfg.ecc_level << ctrl->ecc_level_shift; }else { acc_control &= ~ecc_flags;/* disable RD/WR ECC */ acc_control &= ~brcmnand_ecc_level_mask (ctrl);
@@ -2593,7 +2601,7 @@ static int brcmnand_set_cfg(struct brcmn tmp &= ~brcmnand_ecc_level_mask (ctrl); tmp &= ~brcmnand_spare_area_mask (ctrl);if (ctrl->nand_version >=0x0302 ) { - tmp |= cfg->ecc_level <<NAND_ACC_CONTROL_ECC_SHIFT ; + tmp |= cfg->ecc_level << ctrl->ecc_level_shift; tmp |= cfg->spare_area_size; }nand_writereg (ctrl, acc_control_offs, tmp);
Greg Kroah-Hartman
maintainerPATCH 218/285 Revert "drm/amd/display: Remove v_startup workaround for dcn3+"
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hamza Mahfooz <[email protected]>
commit a81de4a22bbe3183b7f0d6f13f592b8f5b5a3c18 upstream.
This reverts commit 3a31e8b89b7240d9a17ace8a1ed050bdcb560f9e.
We still need to call dcn20_adjust_freesync_v_startup() for older DCN3+ ASICs. Otherwise, it can cause DP to HDMI 2.1 PCONs to fail to light up.
--- .../drm/amd/display/dc/dml/dcn20/dcn20_fpu.c | 24 ++++--------------- 1 file changed, 4 insertions(+), 20 deletions(-)
drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c +4 -20
@@ -1099,6 +1099,10 @@ void dcn20_calculate_dlg_params(struct dc *dc, context->res_ctx.pipe_ctx[i].plane_res.bw.dppclk_khz = pipes[pipe_idx].clks_cfg.dppclk_mhz *1000 ; context->res_ctx.pipe_ctx[i].pipe_dlg_param = pipes[pipe_idx].pipe.dest; +if (context->res_ctx.pipe_ctx[i].stream->adaptive_sync_infopacket.valid) +dcn20_adjust_freesync_v_startup ( + &context->res_ctx.pipe_ctx[i].stream->timing, + &context->res_ctx.pipe_ctx[i].pipe_dlg_param.vstartup_start); pipe_idx++; }
@@ -1927,7 +1931,6 @@ static bool dcn20_validate_bandwidth_internal(struct dc *dc, struct dc_state *coint vlevel =0 ;int pipe_split_from[MAX_PIPES ];int pipe_cnt =0 ; -int i =0 ;display_e2e_pipe_params_st *pipes =kzalloc (dc->res_pool->pipe_count *sizeof (display_e2e_pipe_params_st),GFP_ATOMIC );DC_LOGGER_INIT (dc->ctx->logger);
@@ -1951,15 +1954,6 @@ static bool dcn20_validate_bandwidth_internal(struct dc *dc, struct dc_state *codcn20_calculate_wm (dc, context, pipes, &pipe_cnt, pipe_split_from, vlevel, fast_validate);dcn20_calculate_dlg_params (dc, context, pipes, pipe_cnt, vlevel); -for (i =0 ; i < dc->res_pool->pipe_count; i++) { -if (!context->res_ctx.pipe_ctx[i].stream) -continue ; -if (context->res_ctx.pipe_ctx[i].stream->adaptive_sync_infopacket.valid) -dcn20_adjust_freesync_v_startup ( - &context->res_ctx.pipe_ctx[i].stream->timing, - &context->res_ctx.pipe_ctx[i].pipe_dlg_param.vstartup_start); - } -BW_VAL_TRACE_END_WATERMARKS (); goto validate_out;
@@ -2232,7 +2226,6 @@ bool dcn21_validate_bandwidth_fp(struct dc *dc,int vlevel =0 ;int pipe_split_from[MAX_PIPES ];int pipe_cnt =0 ; -int i =0 ;display_e2e_pipe_params_st *pipes =kzalloc (dc->res_pool->pipe_count *sizeof (display_e2e_pipe_params_st),GFP_ATOMIC );DC_LOGGER_INIT (dc->ctx->logger);
@@ -2261,15 +2254,6 @@ bool dcn21_validate_bandwidth_fp(struct dc *dc,dcn21_calculate_wm (dc, context, pipes, &pipe_cnt, pipe_split_from, vlevel, fast_validate);dcn20_calculate_dlg_params (dc, context, pipes, pipe_cnt, vlevel); -for (i =0 ; i < dc->res_pool->pipe_count; i++) { -if (!context->res_ctx.pipe_ctx[i].stream) -continue ; -if (context->res_ctx.pipe_ctx[i].stream->adaptive_sync_infopacket.valid) -dcn20_adjust_freesync_v_startup ( - &context->res_ctx.pipe_ctx[i].stream->timing, - &context->res_ctx.pipe_ctx[i].pipe_dlg_param.vstartup_start); - } -BW_VAL_TRACE_END_WATERMARKS (); goto validate_out;
Signature · 1 line
2.42.0
Greg Kroah-Hartman
maintainerPATCH 219/285 drm/amd/display: enable cursor degamma for DCN3+ DRM legacy gamma
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Melissa Wen <[email protected]>
commit 57a943ebfcdb4a97fbb409640234bdb44bfa1953 upstream.
For DRM legacy gamma, AMD display manager applies implicit sRGB degamma using a pre-defined sRGB transfer function. It works fine for DCN2 family where degamma ROM and custom curves go to the same color block. But, on DCN3+, degamma is split into two blocks: degamma ROM for pre-defined TFs and gamma correction for user/custom curves and degamma ROM settings doesn't apply to cursor plane. To get DRM legacy gamma working as expected, enable cursor degamma ROM for implict sRGB degamma on HW with this configuration.
--- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c +7 -0
@@ -1260,6 +1260,13 @@ void amdgpu_dm_plane_handle_cursor_updat attributes.rotation_angle =0 ; attributes.attribute_flags.value =0 ; +/* Enable cursor degamma ROM on DCN3+ for implicit sRGB degamma in DRM +* legacy gamma setup. +*/ +if (crtc_state->cm_is_degamma_srgb && + adev->dm.dc->caps.color.dpp.gamma_corr) + attributes.attribute_flags.bits.ENABLE_CURSOR_DEGAMMA =1 ; + attributes.pitch = afb->base.pitches[0 ] / afb->base.format->cpp[0 ];if (crtc_state->stream) {
Greg Kroah-Hartman
maintainerPATCH 220/285 drm/amd/display: limit the v_startup workaround to ASICs older than DCN3.1
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hamza Mahfooz <[email protected]>
commit 47428f4b638d3b3264a2efa1a567b0bbddbb6107 upstream.
Since, calling dcn20_adjust_freesync_v_startup() on DCN3.1+ ASICs can cause the display to flicker and underflow to occur, we shouldn't call it for them. So, ensure that the DCN version is less than DCN_VERSION_3_1 before calling dcn20_adjust_freesync_v_startup().
--- drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/display/dc/dml/dcn20/dcn20_fpu.c +2 -1
@@ -1099,7 +1099,8 @@ void dcn20_calculate_dlg_params(struct d context->res_ctx.pipe_ctx[i].plane_res.bw.dppclk_khz = pipes[pipe_idx].clks_cfg.dppclk_mhz *1000 ; context->res_ctx.pipe_ctx[i].pipe_dlg_param = pipes[pipe_idx].pipe.dest; -if (context->res_ctx.pipe_ctx[i].stream->adaptive_sync_infopacket.valid) +if (dc->ctx->dce_version <DCN_VERSION_3_1 && + context->res_ctx.pipe_ctx[i].stream->adaptive_sync_infopacket.valid)dcn20_adjust_freesync_v_startup ( &context->res_ctx.pipe_ctx[i].stream->timing, &context->res_ctx.pipe_ctx[i].pipe_dlg_param.vstartup_start);
Greg Kroah-Hartman
maintainerPATCH 221/285 drm/amd/display: prevent potential division by zero errors
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hamza Mahfooz <[email protected]>
commit 07e388aab042774f284a2ad75a70a194517cdad4 upstream.
There are two places in apply_below_the_range() where it's possible for a divide by zero error to occur. So, to fix this make sure the divisor is non-zero before attempting the computation in both cases.
--- drivers/gpu/drm/amd/display/modules/freesync/freesync.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/gpu/drm/amd/display/modules/freesync/freesync.c +6 -3
@@ -338,7 +338,9 @@ static void apply_below_the_range(struct* - Delta for CEIL: delta_from_mid_point_in_us_1 * - Delta for FLOOR: delta_from_mid_point_in_us_2 */ -if ((last_render_time_in_us / mid_point_frames_ceil) < in_out_vrr->min_duration_in_us) { +if (mid_point_frames_ceil && + (last_render_time_in_us / mid_point_frames_ceil) < + in_out_vrr->min_duration_in_us) {/* Check for out of range. * If using CEIL produces a value that is out of range, * then we are forced to use FLOOR.
@@ -385,8 +387,9 @@ static void apply_below_the_range(struct/* Either we've calculated the number of frames to insert, * or we need to insert min duration frames */ -if (last_render_time_in_us / frames_to_insert < - in_out_vrr->min_duration_in_us){ +if (frames_to_insert && + (last_render_time_in_us / frames_to_insert) < + in_out_vrr->min_duration_in_us){ frames_to_insert -= (frames_to_insert >1 ) ?1 :0 ; }
Greg Kroah-Hartman
maintainerPATCH 222/285 KVM: VMX: Refresh available regs and IDT vectoring info before NMI handling
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <[email protected]>
commit 50011c2a245792993f2756e5b5b571512bfa409e upstream.
Reset the mask of available "registers" and refresh the IDT vectoring info snapshot in vmx_vcpu_enter_exit(), before KVM potentially handles a an NMI VM-Exit. One of the "registers" that KVM VMX lazily loads is the vmcs.VM_EXIT_INTR_INFO field, which is holds the vector+type on "exception or NMI" VM-Exits, i.e. is needed to identify NMIs. Clearing the available registers bitmask after handling NMIs results in KVM querying info from the last VM-Exit that read vmcs.VM_EXIT_INTR_INFO, and leads to both missed NMIs and spurious NMIs in the host.
Opportunistically grab vmcs.IDT_VECTORING_INFO_FIELD early in the VM-Exit path too, e.g. to guard against similar consumption of stale data. The field is read on every "normal" VM-Exit, and there's no point in delaying the inevitable.
--- arch/x86/kvm/vmx/vmx.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-)
arch/x86/kvm/vmx/vmx.c +11 -10
@@ -7243,13 +7243,20 @@ static noinstr void vmx_vcpu_enter_exit( flags); vcpu->arch.cr2 =native_read_cr2 (); + vcpu->arch.regs_avail &= ~VMX_REGS_LAZY_LOAD_SET ; + + vmx->idt_vectoring_info =0 ;vmx_enable_fb_clear (vmx); -if (unlikely (vmx->fail)) +if (unlikely (vmx->fail)) { vmx->exit_reason.full =0xdead ; -else - vmx->exit_reason.full =vmcs_read32 (VM_EXIT_REASON ); + goto out; + } + + vmx->exit_reason.full =vmcs_read32 (VM_EXIT_REASON ); +if (likely (!vmx->exit_reason.failed_vmentry)) + vmx->idt_vectoring_info =vmcs_read32 (IDT_VECTORING_INFO_FIELD );if ((u16 )vmx->exit_reason.basic ==EXIT_REASON_EXCEPTION_NMI &&is_nmi (vmx_get_intr_info (vcpu))) {
@@ -7258,6 +7265,7 @@ static noinstr void vmx_vcpu_enter_exit(kvm_after_interrupt (vcpu); } +out:guest_state_exit_irqoff (); }
@@ -7379,8 +7387,6 @@ static fastpath_t vmx_vcpu_run(struct kvloadsegment (es, __USER_DS);#endif - vcpu->arch.regs_avail &= ~VMX_REGS_LAZY_LOAD_SET ; -pt_guest_exit (vmx);kvm_load_host_xsave_state (vcpu);
@@ -7397,17 +7403,12 @@ static fastpath_t vmx_vcpu_run(struct kv vmx->nested.nested_run_pending =0 ; } - vmx->idt_vectoring_info =0 ; -if (unlikely (vmx->fail))return EXIT_FASTPATH_NONE ;if (unlikely ((u16 )vmx->exit_reason.basic ==EXIT_REASON_MCE_DURING_VMENTRY ))kvm_machine_check (); -if (likely (!vmx->exit_reason.failed_vmentry)) - vmx->idt_vectoring_info =vmcs_read32 (IDT_VECTORING_INFO_FIELD ); -trace_kvm_exit (vcpu,KVM_ISA_VMX );if (unlikely (vmx->exit_reason.failed_vmentry))
Greg Kroah-Hartman
maintainerPATCH 223/285 KVM: SVM: Take and hold ir_list_lock when updating vCPUs Physical ID entry
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <[email protected]>
commit 4c08e737f056fec930b416a2bd37ed266d724f95 upstream.
Hoist the acquisition of ir_list_lock from avic_update_iommu_vcpu_affinity() to its two callers, avic_vcpu_load() and avic_vcpu_put(), specifically to encapsulate the write to the vCPU's entry in the AVIC Physical ID table. This will allow a future fix to pull information from the Physical ID entry when updating the IRTE, without potentially consuming stale information, i.e. without racing with the vCPU being (un)loaded.
Add a comment to call out that ir_list_lock does NOT protect against multiple writers, specifically that reading the Physical ID entry in avic_vcpu_put() outside of the lock is safe.
To preserve some semblance of independence from ir_list_lock, keep the READ_ONCE() in avic_vcpu_load() even though acuiring the spinlock effectively ensures the load(s) will be generated after acquiring the lock.
--- arch/x86/kvm/svm/avic.c | 31 +++++++++++++++++++++++-------- 1 file changed, 23 insertions(+), 8 deletions(-)
arch/x86/kvm/svm/avic.c +23 -8
@@ -986,10 +986,11 @@ static inline int avic_update_iommu_vcpu_affinity(struct kvm_vcpu *vcpu, int cpu, bool r) { int ret = 0; -unsigned long flags;struct amd_svm_iommu_ir *ir;struct vcpu_svm *svm =to_svm (vcpu); +lockdep_assert_held (&svm->ir_list_lock); +if (!kvm_arch_has_assigned_device (vcpu->kvm))return 0 ;
@@ -997,19 +998,15 @@ avic_update_iommu_vcpu_affinity(struct k* Here, we go through the per-vcpu ir_list to update all existing * interrupt remapping table entry targeting this vcpu. */ -spin_lock_irqsave (&svm->ir_list_lock, flags); -if (list_empty (&svm->ir_list)) - goto out; +return 0 ;list_for_each_entry (ir, &svm->ir_list, node) { ret =amd_iommu_update_ga (cpu, r, ir->data);if (ret) -break ; +return ret; } -out: -spin_unlock_irqrestore (&svm->ir_list_lock, flags); -return ret; +return 0 ; }void avic_vcpu_load (struct kvm_vcpu *vcpu,int cpu)
@@ -1017,6 +1014,7 @@ void avic_vcpu_load(struct kvm_vcpu *vcpu64 entry;int h_physical_id =kvm_cpu_get_apicid (cpu);struct vcpu_svm *svm =to_svm (vcpu); +unsigned long flags;lockdep_assert_preemption_disabled ();
@@ -1033,6 +1031,8 @@ void avic_vcpu_load(struct kvm_vcpu *vcpif (kvm_vcpu_is_blocking (vcpu))return ; +spin_lock_irqsave (&svm->ir_list_lock, flags); + entry =READ_ONCE (*(svm->avic_physical_id_cache));WARN_ON_ONCE (entry &AVIC_PHYSICAL_ID_ENTRY_IS_RUNNING_MASK );
@@ -1042,25 +1042,40 @@ void avic_vcpu_load(struct kvm_vcpu *vcpWRITE_ONCE (*(svm->avic_physical_id_cache), entry);avic_update_iommu_vcpu_affinity (vcpu, h_physical_id, true); + +spin_unlock_irqrestore (&svm->ir_list_lock, flags); }void avic_vcpu_put (struct kvm_vcpu *vcpu) {u64 entry;struct vcpu_svm *svm =to_svm (vcpu); +unsigned long flags;lockdep_assert_preemption_disabled (); +/* +* Note, reading the Physical ID entry outside of ir_list_lock is safe +* as only the pCPU that has loaded (or is loading) the vCPU is allowed +* to modify the entry, and preemption is disabled. I.e. the vCPU +* can't be scheduled out and thus avic_vcpu_{put,load}() can't run +* recursively. +*/ entry =READ_ONCE (*(svm->avic_physical_id_cache));/* Nothing to do if IsRunning == '0' due to vCPU blocking. */ if (!(entry &AVIC_PHYSICAL_ID_ENTRY_IS_RUNNING_MASK ))return ; +spin_lock_irqsave (&svm->ir_list_lock, flags); +avic_update_iommu_vcpu_affinity (vcpu,-1 ,0 ); entry &= ~AVIC_PHYSICAL_ID_ENTRY_IS_RUNNING_MASK ;WRITE_ONCE (*(svm->avic_physical_id_cache), entry); + +spin_unlock_irqrestore (&svm->ir_list_lock, flags); + }void avic_refresh_virtual_apic_mode (struct kvm_vcpu *vcpu)
Greg Kroah-Hartman
maintainerPATCH 224/285 KVM: SVM: Dont inject #UD if KVM attempts to skip SEV guest insn
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <[email protected]>
commit cb49631ad111570f1bad37702c11c2ae07fa2e3c upstream.
Don't inject a #UD if KVM attempts to "emulate" to skip an instruction for an SEV guest, and instead resume the guest and hope that it can make forward progress. When commit 04c40f344def ("KVM: SVM: Inject #UD on attempted emulation for SEV guest w/o insn buffer") added the completely arbitrary #UD behavior, there were no known scenarios where a well-behaved guest would induce a VM-Exit that triggered emulation, i.e. it was thought that injecting #UD would be helpful.
However, now that KVM (correctly) attempts to re-inject INT3/INTO, e.g. if a #NPF is encountered when attempting to deliver the INT3/INTO, an SEV guest can trigger emulation without a buffer, through no fault of its own. Resuming the guest and retrying the INT3/INTO is architecturally wrong, e.g. the vCPU will incorrectly re-hit code #DBs, but for SEV guests there is literally no other option that has a chance of making forward progress.
Drop the #UD injection for all "skip" emulation, not just those related to INT3/INTO, even though that means that the guest will likely end up in an infinite loop instead of getting a #UD (the vCPU may also crash, e.g. if KVM emulated everything about an instruction except for advancing RIP). There's no evidence that suggests that an unexpected #UD is actually better than hanging the vCPU, e.g. a soft-hung vCPU can still respond to IRQs and NMIs to generate a backtrace.
--- arch/x86/kvm/svm/svm.c | 35 +++++++++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 8 deletions(-)
arch/x86/kvm/svm/svm.c +27 -8
@@ -365,6 +365,8 @@ static void svm_set_interrupt_shadow(str svm->vmcb->control.int_state |=SVM_INTERRUPT_SHADOW_MASK ; } +static bool svm_can_emulate_instruction (struct kvm_vcpu *vcpu,int emul_type, +void *insn,int insn_len);static int __svm_skip_emulated_instruction (struct kvm_vcpu *vcpu,bool commit_side_effects)
@@ -385,6 +387,14 @@ static int __svm_skip_emulated_instructi }if (!svm->next_rip) { +/* +* FIXME: Drop this when kvm_emulate_instruction() does the +* right thing and treats "can't emulate" as outright failure +* for EMULTYPE_SKIP. +*/ +if (!svm_can_emulate_instruction (vcpu,EMULTYPE_SKIP ,NULL ,0 )) +return 0 ; +if (unlikely (!commit_side_effects)) old_rflags = svm->vmcb->save.rflags;
@@ -4651,16 +4661,25 @@ static bool svm_can_emulate_instruction(* and cannot be decrypted by KVM, i.e. KVM would read cyphertext and * decode garbage. * -* Inject #UD if KVM reached this point without an instruction buffer. -* In practice, this path should never be hit by a well-behaved guest, -* e.g. KVM doesn't intercept #UD or #GP for SEV guests, but this path -* is still theoretically reachable, e.g. via unaccelerated fault-like -* AVIC access, and needs to be handled by KVM to avoid putting the -* guest into an infinite loop. Injecting #UD is somewhat arbitrary, -* but its the least awful option given lack of insight into the guest. +* If KVM is NOT trying to simply skip an instruction, inject #UD if +* KVM reached this point without an instruction buffer. In practice, +* this path should never be hit by a well-behaved guest, e.g. KVM +* doesn't intercept #UD or #GP for SEV guests, but this path is still +* theoretically reachable, e.g. via unaccelerated fault-like AVIC +* access, and needs to be handled by KVM to avoid putting the guest +* into an infinite loop. Injecting #UD is somewhat arbitrary, but +* its the least awful option given lack of insight into the guest. +* +* If KVM is trying to skip an instruction, simply resume the guest. +* If a #NPF occurs while the guest is vectoring an INT3/INTO, then KVM +* will attempt to re-inject the INT3/INTO and skip the instruction. +* In that scenario, retrying the INT3/INTO and hoping the guest will +* make forward progress is the only option that has a chance of +* success (and in practice it will work the vast majority of the time). */ if (unlikely (!insn)) { -kvm_queue_exception (vcpu,UD_VECTOR ); +if (!(emul_type &EMULTYPE_SKIP )) +kvm_queue_exception (vcpu,UD_VECTOR );return false; }
Greg Kroah-Hartman
maintainerPATCH 225/285 KVM: SVM: Get source vCPUs from source VM for SEV-ES intrahost migration
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <[email protected]>
commit f1187ef24eb8f36e8ad8106d22615ceddeea6097 upstream.
Fix a goof where KVM tries to grab source vCPUs from the destination VM when doing intrahost migration. Grabbing the wrong vCPU not only hoses the guest, it also crashes the host due to the VMSA pointer being left NULL.
BUG: unable to handle page fault for address: ffffe38687000000 #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page PGD 0 P4D 0 Oops: 0000 [#1] SMP NOPTI CPU: 39 PID: 17143 Comm: sev_migrate_tes Tainted: GO 6.5.0-smp--fff2e47e6c3b-next #151 Hardware name: Google, Inc. Arcadia_IT_80/Arcadia_IT_80, BIOS 34.28.0 07/10/2023 RIP: 0010:__free_pages+0x15/0xd0 RSP: 0018:ffff923fcf6e3c78 EFLAGS: 00010246 RAX: 0000000000000000 RBX: ffffe38687000000 RCX: 0000000000000100 RDX: 0000000000000100 RSI: 0000000000000000 RDI: ffffe38687000000 RBP: ffff923fcf6e3c88 R08: ffff923fcafb0000 R09: 0000000000000000 R10: 0000000000000000 R11: ffffffff83619b90 R12: ffff923fa9540000 R13: 0000000000080007 R14: ffff923f6d35d000 R15: 0000000000000000 FS: 0000000000000000(0000) GS:ffff929d0d7c0000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: ffffe38687000000 CR3: 0000005224c34005 CR4: 0000000000770ee0 PKRU: 55555554 Call Trace: <TASK> sev_free_vcpu+0xcb/0x110 [kvm_amd] svm_vcpu_free+0x75/0xf0 [kvm_amd] kvm_arch_vcpu_destroy+0x36/0x140 [kvm] kvm_destroy_vcpus+0x67/0x100 [kvm] kvm_arch_destroy_vm+0x161/0x1d0 [kvm] kvm_put_kvm+0x276/0x560 [kvm] kvm_vm_release+0x25/0x30 [kvm] __fput+0x106/0x280 ____fput+0x12/0x20 task_work_run+0x86/0xb0 do_exit+0x2e3/0x9c0 do_group_exit+0xb1/0xc0 __x64_sys_exit_group+0x1b/0x20 do_syscall_64+0x41/0x90 entry_SYSCALL_64_after_hwframe+0x63/0xcd </TASK> CR2: ffffe38687000000
--- arch/x86/kvm/svm/sev.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/x86/kvm/svm/sev.c +1 -1
@@ -1725,7 +1725,7 @@ static void sev_migrate_from(struct kvm* Note, the source is not required to have the same number of * vCPUs as the destination when migrating a vanilla SEV VM. */ - src_vcpu =kvm_get_vcpu (dst_kvm, i); + src_vcpu =kvm_get_vcpu (src_kvm, i); src_svm =to_svm (src_vcpu);/*
Greg Kroah-Hartman
maintainerPATCH 226/285 KVM: nSVM: Check instead of asserting on nested TSC scaling support
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <[email protected]>
commit 7cafe9b8e22bb3d77f130c461aedf6868c4aaf58 upstream.
Check for nested TSC scaling support on nested SVM VMRUN instead of asserting that TSC scaling is exposed to L1 if L1's MSR_AMD64_TSC_RATIO has diverged from KVM's default. Userspace can trigger the WARN at will by writing the MSR and then updating guest CPUID to hide the feature (modifying guest CPUID is allowed anytime before KVM_RUN). E.g. hacking KVM's state_test selftest to do
vcpu_set_msr(vcpu, MSR_AMD64_TSC_RATIO, 0); vcpu_clear_cpuid_feature(vcpu, X86_FEATURE_TSCRATEMSR);
after restoring state in a new VM+vCPU yields an endless supply of:
------------[ cut here ]------------
WARNING: CPU: 164 PID: 62565 at arch/x86/kvm/svm/nested.c:699
nested_vmcb02_prepare_control+0x3d6/0x3f0 [kvm_amd]
Call Trace:
<TASK>
enter_svm_guest_mode+0x114/0x560 [kvm_amd]
nested_svm_vmrun+0x260/0x330 [kvm_amd]
vmrun_interception+0x29/0x30 [kvm_amd]
svm_invoke_exit_handler+0x35/0x100 [kvm_amd]
svm_handle_exit+0xe7/0x180 [kvm_amd]
kvm_arch_vcpu_ioctl_run+0x1eab/0x2570 [kvm]
kvm_vcpu_ioctl+0x4c9/0x5b0 [kvm]
__se_sys_ioctl+0x7a/0xc0
__x64_sys_ioctl+0x21/0x30
do_syscall_64+0x41/0x90
entry_SYSCALL_64_after_hwframe+0x63/0xcd
RIP: 0033:0x45ca1bNote, the nested #VMEXIT path has the same flaw, but needs a different fix and will be handled separately.
--- arch/x86/kvm/svm/nested.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
arch/x86/kvm/svm/nested.c +2 -3
@@ -695,10 +695,9 @@ static void nested_vmcb02_prepare_contro vmcb02->control.tsc_offset = vcpu->arch.tsc_offset; -if (svm->tsc_ratio_msr != kvm_caps.default_tsc_scaling_ratio) { -WARN_ON (!svm->tsc_scaling_enabled); +if (svm->tsc_scaling_enabled && + svm->tsc_ratio_msr != kvm_caps.default_tsc_scaling_ratio)nested_svm_update_tsc_ratio_msr (vcpu); - } vmcb02->control.int_ctl = (svm->nested.ctl.int_ctl & int_ctl_vmcb12_bits) |
Greg Kroah-Hartman
maintainerPATCH 227/285 KVM: nSVM: Load L1s TSC multiplier based on L1 state, not L2 state
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <[email protected]>
commit 0c94e2468491cbf0754f49a5136ab51294a96b69 upstream.
When emulating nested VM-Exit, load L1's TSC multiplier if L1's desired ratio doesn't match the current ratio, not if the ratio L1 is using for L2 diverges from the default. Functionally, the end result is the same as KVM will run L2 with L1's multiplier if L2's multiplier is the default, i.e. checking that L1's multiplier is loaded is equivalent to checking if L2 has a non-default multiplier.
However, the assertion that TSC scaling is exposed to L1 is flawed, as userspace can trigger the WARN at will by writing the MSR and then updating guest CPUID to hide the feature (modifying guest CPUID is allowed anytime before KVM_RUN). E.g. hacking KVM's state_test selftest to do
vcpu_set_msr(vcpu, MSR_AMD64_TSC_RATIO, 0);
vcpu_clear_cpuid_feature(vcpu, X86_FEATURE_TSCRATEMSR);after restoring state in a new VM+vCPU yields an endless supply of:
------------[ cut here ]------------
WARNING: CPU: 10 PID: 206939 at arch/x86/kvm/svm/nested.c:1105
nested_svm_vmexit+0x6af/0x720 [kvm_amd]
Call Trace:
nested_svm_exit_handled+0x102/0x1f0 [kvm_amd]
svm_handle_exit+0xb9/0x180 [kvm_amd]
kvm_arch_vcpu_ioctl_run+0x1eab/0x2570 [kvm]
kvm_vcpu_ioctl+0x4c9/0x5b0 [kvm]
? trace_hardirqs_off+0x4d/0xa0
__se_sys_ioctl+0x7a/0xc0
__x64_sys_ioctl+0x21/0x30
do_syscall_64+0x41/0x90
entry_SYSCALL_64_after_hwframe+0x63/0xcdUnlike the nested VMRUN path, hoisting the svm->tsc_scaling_enabled check into the if-statement is wrong as KVM needs to ensure L1's multiplier is
loaded in the above scenario. Alternatively, the WARN_ON() could simply
be deleted, but that would make KVM's behavior even more subtle, e.g. it's not immediately obvious why it's safe to write MSR_AMD64_TSC_RATIO when checking only tsc_ratio_msr.
--- arch/x86/kvm/svm/nested.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/x86/kvm/svm/nested.c +2 -2
@@ -1100,8 +1100,8 @@ int nested_svm_vmexit(struct vcpu_svm *svmcb_mark_dirty (vmcb01,VMCB_INTERCEPTS ); } -if (svm->tsc_ratio_msr != kvm_caps.default_tsc_scaling_ratio) { -WARN_ON (!svm->tsc_scaling_enabled); +if (kvm_caps.has_tsc_control && + vcpu->arch.tsc_scaling_ratio != vcpu->arch.l1_tsc_scaling_ratio) { vcpu->arch.tsc_scaling_ratio = vcpu->arch.l1_tsc_scaling_ratio;__svm_write_tsc_multiplier (vcpu->arch.tsc_scaling_ratio); }
Greg Kroah-Hartman
maintainerPATCH 228/285 KVM: SVM: Set target pCPU during IRTE update if target vCPU is running
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <[email protected]>
commit f3cebc75e7425d6949d726bb8e937095b0aef025 upstream.
Update the target pCPU for IOMMU doorbells when updating IRTE routing if KVM is actively running the associated vCPU. KVM currently only updates the pCPU when loading the vCPU (via avic_vcpu_load()), and so doorbell events will be delayed until the vCPU goes through a put+load cycle (which might very well "never" happen for the lifetime of the VM).
To avoid inserting a stale pCPU, e.g. due to racing between updating IRTE routing and vCPU load/put, get the pCPU information from the vCPU's Physical APIC ID table entry (a.k.a. avic_physical_id_cache in KVM) and update the IRTE while holding ir_list_lock. Add comments with --verbose enabled to explain exactly what is and isn't protected by ir_list_lock.
--- arch/x86/kvm/svm/avic.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+)
arch/x86/kvm/svm/avic.c +28 -0
@@ -791,6 +791,7 @@ static int svm_ir_list_add(struct vcpu_sint ret =0 ;unsigned long flags;struct amd_svm_iommu_ir *ir; +u64 entry;/** * In some cases, the existing irte is updated and re-set,
@@ -824,6 +825,18 @@ static int svm_ir_list_add(struct vcpu_s ir->data = pi->ir_data;spin_lock_irqsave (&svm->ir_list_lock, flags); + +/* +* Update the target pCPU for IOMMU doorbells if the vCPU is running. +* If the vCPU is NOT running, i.e. is blocking or scheduled out, KVM +* will update the pCPU info when the vCPU awkened and/or scheduled in. +* See also avic_vcpu_load(). +*/ + entry =READ_ONCE (*(svm->avic_physical_id_cache)); +if (entry &AVIC_PHYSICAL_ID_ENTRY_IS_RUNNING_MASK ) +amd_iommu_update_ga (entry &AVIC_PHYSICAL_ID_ENTRY_HOST_PHYSICAL_ID_MASK , + true, pi->ir_data); +list_add (&ir->node, &svm->ir_list);spin_unlock_irqrestore (&svm->ir_list_lock, flags); out:
@@ -1031,6 +1044,13 @@ void avic_vcpu_load(struct kvm_vcpu *vcpif (kvm_vcpu_is_blocking (vcpu))return ; +/* +* Grab the per-vCPU interrupt remapping lock even if the VM doesn't +* _currently_ have assigned devices, as that can change. Holding +* ir_list_lock ensures that either svm_ir_list_add() will consume +* up-to-date entry information, or that this task will wait until +* svm_ir_list_add() completes to set the new target pCPU. +*/ spin_lock_irqsave (&svm->ir_list_lock, flags); entry =READ_ONCE (*(svm->avic_physical_id_cache));
@@ -1067,6 +1087,14 @@ void avic_vcpu_put(struct kvm_vcpu *vcpuif (!(entry &AVIC_PHYSICAL_ID_ENTRY_IS_RUNNING_MASK ))return ; +/* +* Take and hold the per-vCPU interrupt remapping lock while updating +* the Physical ID entry even though the lock doesn't protect against +* multiple writers (see above). Holding ir_list_lock ensures that +* either svm_ir_list_add() will consume up-to-date entry information, +* or that this task will wait until svm_ir_list_add() completes to +* mark the vCPU as not running. +*/ spin_lock_irqsave (&svm->ir_list_lock, flags);avic_update_iommu_vcpu_affinity (vcpu,-1 ,0 );
Greg Kroah-Hartman
maintainerPATCH 229/285 KVM: SVM: Skip VMSA init in sev_es_init_vmcb() if pointer is NULL
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <[email protected]>
commit 1952e74da96fb3e48b72a2d0ece78c688a5848c1 upstream.
Skip initializing the VMSA physical address in the VMCB if the VMSA is NULL, which occurs during intrahost migration as KVM initializes the VMCB before copying over state from the source to the destination (including the VMSA and its physical address).
In normal builds, __pa() is just math, so the bug isn't fatal, but with CONFIG_DEBUG_VIRTUAL=y, the validity of the virtual address is verified and passing in NULL will make the kernel unhappy.
--- arch/x86/kvm/svm/sev.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
arch/x86/kvm/svm/sev.c +5 -2
@@ -2955,9 +2955,12 @@ static void sev_es_init_vmcb(struct vcpu/* * An SEV-ES guest requires a VMSA area that is a separate from the * VMCB page. Do not include the encryption mask on the VMSA physical -* address since hardware will access it using the guest key. +* address since hardware will access it using the guest key. Note, +* the VMSA will be NULL if this vCPU is the destination for intrahost +* migration, and will be copied later. */ - svm->vmcb->control.vmsa_pa =__pa (svm->sev_es.vmsa); +if (svm->sev_es.vmsa) + svm->vmcb->control.vmsa_pa =__pa (svm->sev_es.vmsa);/* Can't intercept CR register access, HV can't modify CR registers */ svm_clr_intercept (svm,INTERCEPT_CR0_READ );
Greg Kroah-Hartman
maintainerPATCH 230/285 MIPS: Only fiddle with CHECKFLAGS if `need-compiler
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maciej W. Rozycki <[email protected]>
commit 4fe4a6374c4db9ae2b849b61e84b58685dca565a upstream.
We have originally guarded fiddling with CHECKFLAGS in our arch Makefile by checking for the CONFIG_MIPS variable, not set for targets such as distclean', etc. that neither include .config' nor use the compiler.
Starting from commit 805b2e1d427a ("kbuild: include Makefile.compiler only when compiler is needed") we have had a generic `need-compiler' variable explicitly telling us if the compiler will be used and thus its capabilities need to be checked and expressed in the form of compilation flags. If this variable is not set, then make' functions such as cc-option' are undefined, causing all kinds of weirdness to happen if we expect specific results to be returned, most recently:
cc1: error: '-mloongson-mmi' must be used with '-mhard-float'
messages with configurations such as fuloong2e_defconfig' and the modules_install' target, which does include `.config' and yet does not use the compiler.
Replace the check for CONFIG_MIPS with one for `need-compiler' instead, so as to prevent the compiler from being ever called for CHECKFLAGS when not needed.
--- arch/mips/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/mips/Makefile +1 -1
@@ -341,7 +341,7 @@ KBUILD_CFLAGS += -fno-asynchronous-unwin KBUILD_LDFLAGS += -m $(ld-emul) -ifdef CONFIG_MIPS +ifdef need-compiler CHECKFLAGS += $(shell $(CC) $(KBUILD_CPPFLAGS) $(KBUILD_CFLAGS) -dM -E -x c /dev/null | \ grep -E -vw '__GNUC_(MINOR_|PATCHLEVEL_)?_' | \ sed -e "s/^\#define /-D'/" -e "s/ /'='/" -e "s/$$/'/" -e 's/\$$/&&/g')
Greg Kroah-Hartman
maintainerPATCH 231/285 MIPS: Fix CONFIG_CPU_DADDI_WORKAROUNDS `modules_install regression
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maciej W. Rozycki <[email protected]>
commit a79a404e6c2241ebc528b9ebf4c0832457b498c3 upstream.
Remove a build-time check for the presence of the GCC `-msym32' option. This option has been there since GCC 4.1.0, which is below the minimum required as at commit 805b2e1d427a ("kbuild: include Makefile.compiler only when compiler is needed"), when an error message:
arch/mips/Makefile:306: *** CONFIG_CPU_DADDI_WORKAROUNDS unsupported without -msym32. Stop.
started to trigger for the modules_install' target with configurations such as decstation_64_defconfig' that set CONFIG_CPU_DADDI_WORKAROUNDS, because said commit has made `cc-option-yn' an undefined function for non-build targets.
--- arch/mips/Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/mips/Makefile +2 -2
@@ -299,8 +299,8 @@ ifdef CONFIG_64BIT endif endif - ifeq ($(KBUILD_SYM32)$(call cc-option-yn,-msym32), yy) - cflags-y += -msym32 -DKBUILD_64BIT_SYM32 + ifeq ($(KBUILD_SYM32), y) + cflags-$(KBUILD_SYM32) += -msym32 -DKBUILD_64BIT_SYM32 else ifeq ($(CONFIG_CPU_DADDI_WORKAROUNDS), y) $(error CONFIG_CPU_DADDI_WORKAROUNDS unsupported without -msym32)
Greg Kroah-Hartman
maintainerPATCH 232/285 perf hists browser: Fix hierarchy mode header
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namhyung Kim <[email protected]>
commit e2cabf2a44791f01c21f8d5189b946926e34142e upstream.
The commit ef9ff6017e3c4593 ("perf ui browser: Move the extra title lines from the hists browser") introduced ui_browser__gotorc_title() to help moving non-title lines easily. But it missed to update the title for the hierarchy mode so it won't print the header line on TUI at all.
$ perf report --hierarchy
--- tools/perf/ui/browsers/hists.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/ui/browsers/hists.c +1 -1
@@ -1779,7 +1779,7 @@ static void hists_browser__hierarchy_heahists_browser__scnprintf_hierarchy_headers (browser, headers,sizeof (headers)); -ui_browser__gotorc (&browser->b,0 ,0 ); +ui_browser__gotorc_title (&browser->b,0 ,0 );ui_browser__set_color (&browser->b,HE_COLORSET_ROOT );ui_browser__write_nstring (&browser->b, headers, browser->b.width +1 ); }
Greg Kroah-Hartman
maintainerPATCH 233/285 perf build: Update build rule for generated files
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namhyung Kim <[email protected]>
commit 7822a8913f4c51c7d1aff793b525d60c3384fb5b upstream.
The bison and flex generate C files from the source (.y and .l) files. When O= option is used, they are saved in a separate directory but the default build rule assumes the .C files are in the source directory. So it might read invalid file if there are generated files from an old version. The same is true for the pmu-events files.
For example, the following command would cause a build failure:
$ git checkout v6.3 $ make -C tools/perf # build in the same directory
$ git checkout v6.5-rc2
$ mkdir build # create a build directory
$ make -C tools/perf O=build # build in a different directory but it
# refers files in the source directoryLet's update the build rule to specify those cases explicitly to depend on the files in the output directory.
Note that it's not a complete fix and it needs the next patch for the include path too.
--- tools/build/Makefile.build | 10 ++++++++++ tools/perf/pmu-events/Build | 6 ++++++ 2 files changed, 16 insertions(+)
tools/build/Makefile.build +10 -0
@@ -117,6 +117,16 @@ $(OUTPUT)%.s: %.c FORCE $(call rule_mkdir) $(call if_changed_dep,cc_s_c) +# bison and flex files are generated in the OUTPUT directory +# so it needs a separate rule to depend on them properly +$(OUTPUT)%-bison.o: $(OUTPUT)%-bison.c FORCE + $(call rule_mkdir) + $(call if_changed_dep,$(host)cc_o_c) + +$(OUTPUT)%-flex.o: $(OUTPUT)%-flex.c FORCE + $(call rule_mkdir) + $(call if_changed_dep,$(host)cc_o_c) + # Gather build data: # obj-y - list of build objects # subdir-y - list of directories to nest
tools/perf/pmu-events/Build +6 -0
@@ -35,3 +35,9 @@ $(PMU_EVENTS_C): $(JSON) $(JSON_TEST) $( $(call rule_mkdir) $(Q)$(call echo-cmd,gen)$(PYTHON) $(JEVENTS_PY) $(JEVENTS_ARCH) $(JEVENTS_MODEL) pmu-events/arch $@ endif + +# pmu-events.c file is generated in the OUTPUT directory so it needs a +# separate rule to depend on it properly +$(OUTPUT)pmu-events/pmu-events.o: $(PMU_EVENTS_C) + $(call rule_mkdir) + $(call if_changed_dep,cc_o_c)
Greg Kroah-Hartman
maintainerPATCH 234/285 perf test shell stat_bpf_counters: Fix test on Intel
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namhyung Kim <[email protected]>
commit 68ca249c964f520af7f8763e22f12bd26b57b870 upstream.
As of now, bpf counters (bperf) don't support event groups. But the default perf stat includes topdown metrics if supported (on recent Intel machines) which require groups. That makes perf stat exiting.
$ sudo perf stat --bpf-counter true bpf managed perf events do not yet support groups.
Actually the test explicitly uses cycles event only, but it missed to pass the option when it checks the availability of the command.
--- tools/perf/tests/shell/stat_bpf_counters.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
tools/perf/tests/shell/stat_bpf_counters.sh +2 -2
@@ -22,10 +22,10 @@ compare_number() } # skip if --bpf-counters is not supported -if ! perf stat --bpf-counters true > /dev/null 2>&1; then +if ! perf stat -e cycles --bpf-counters true > /dev/null 2>&1; then if [ "$1" = "-v" ]; then echo "Skipping: --bpf-counters not supported" - perf --no-pager stat --bpf-counters true || true + perf --no-pager stat -e cycles --bpf-counters true || true fi exit 2 fi
Greg Kroah-Hartman
maintainerPATCH 235/285 perf tools: Handle old data in PERF_RECORD_ATTR
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namhyung Kim <[email protected]>
commit 9bf63282ea77a531ea58acb42fb3f40d2d1e4497 upstream.
The PERF_RECORD_ATTR is used for a pipe mode to describe an event with attribute and IDs. The ID table comes after the attr and it calculate size of the table using the total record size and the attr size.
n_ids = (total_record_size - end_of_the_attr_field) / sizeof(u64)
This is fine for most use cases, but sometimes it saves the pipe output in a file and then process it later. And it becomes a problem if there is a change in attr size between the record and report.
$ perf record -o- > perf-pipe.data # old version $ perf report -i- < perf-pipe.data # new version
For example, if the attr size is 128 and it has 4 IDs, then it would save them in 168 byte like below:
8 byte: perf event header { .type = PERF_RECORD_ATTR, .size = 168 },
128 byte: perf event attr { .size = 128, ... },
32 byte: event IDs [] = { 1234, 1235, 1236, 1237 },
But when report later, it thinks the attr size is 136 then it only read the last 3 entries as ID.
8 byte: perf event header { .type = PERF_RECORD_ATTR, .size = 168 },
136 byte: perf event attr { .size = 136, ... },
24 byte: event IDs [] = { 1235, 1236, 1237 }, // 1234 is missing
So it should use the recorded version of the attr. The attr has the size field already then it should honor the size when reading data.
--- tools/perf/util/header.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
tools/perf/util/header.c +6 -5
@@ -4382,7 +4382,8 @@ int perf_event__process_attr(struct perfunion perf_event *event, struct evlist **pevlist) { - u32 i, ids, n_ids; + u32 i, n_ids; +u64 *ids;struct evsel *evsel;struct evlist *evlist = *pevlist;
@@ -4398,9 +4399,8 @@ int perf_event__process_attr(struct perfevlist__add (evlist, evsel); - ids = event->header.size; - ids -= (void *)&event->attr.id - (void *)event; - n_ids = ids /sizeof (u64); + n_ids = event->header.size -sizeof (event->header) - event->attr.attr.size; + n_ids = n_ids /sizeof (u64);/* * We don't have the cpu and thread maps on the header, so * for allocating the perf_sample_id table we fake 1 cpu and
@@ -4409,8 +4409,9 @@ int perf_event__process_attr(struct perfif (perf_evsel__alloc_id (&evsel->core,1 , n_ids))return -ENOMEM ; + ids = (void *)&event->attr.attr + event->attr.attr.size;for (i =0 ; i < n_ids; i++) { -perf_evlist__id_add (&evlist->core, &evsel->core,0 , i, event->attr.id[i]); +perf_evlist__id_add (&evlist->core, &evsel->core,0 , i, ids[i]); }return 0 ;
Greg Kroah-Hartman
maintainerPATCH 236/285 perf build: Include generated header files properly
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namhyung Kim <[email protected]>
commit c7e97f215a4ad634b746804679f5937d25f77e29 upstream.
The flex and bison generate header files from the source. When user specified a build directory with O= option, it'd generate files under the directory. The build command has -I option to specify the header include directory.
But the -I option only affects the files included like <...>. Let's change the flex and bison headers to use it instead of "...".
--- tools/perf/pmu-events/jevents.py | 2 +- tools/perf/util/bpf-filter.c | 4 ++-- tools/perf/util/expr.c | 4 ++-- tools/perf/util/parse-events.c | 4 ++-- tools/perf/util/pmu.c | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-)
tools/perf/pmu-events/jevents.py +1 -1
@@ -999,7 +999,7 @@ such as "arm/cortex-a34".''', _args = ap.parse_args() _args.output_file.write(""" -#include "pmu-events/pmu-events.h" +#include <pmu-events/pmu-events.h> #include "util/header.h" #include "util/pmu.h" #include <string.h>
tools/perf/util/bpf-filter.c +2 -2
@@ -9,8 +9,8 @@#include "util/evsel.h" #include "util/bpf-filter.h" -#include "util/bpf-filter-flex.h" -#include "util/bpf-filter-bison.h" +#include <util/bpf-filter-flex.h> +#include <util/bpf-filter-bison.h> #include "bpf_skel/sample-filter.h" #include "bpf_skel/sample_filter.skel.h"
tools/perf/util/expr.c +2 -2
@@ -10,8 +10,8 @@#include "debug.h" #include "evlist.h" #include "expr.h" -#include "expr-bison.h" -#include "expr-flex.h" +#include <util/expr-bison.h> +#include <util/expr-flex.h> #include "util/hashmap.h" #include "smt.h" #include "tsc.h"
tools/perf/util/parse-events.c +2 -2
@@ -18,8 +18,8 @@#include "debug.h" #include <api/fs/tracing_path.h> #include <perf/cpumap.h> -#include "parse-events-bison.h" -#include "parse-events-flex.h" +#include <util/parse-events-bison.h> +#include <util/parse-events-flex.h> #include "pmu.h" #include "pmus.h" #include "asm/bug.h"
tools/perf/util/pmu.c +2 -2
@@ -19,8 +19,8 @@#include "evsel.h" #include "pmu.h" #include "pmus.h" -#include "pmu-bison.h" -#include "pmu-flex.h" +#include <util/pmu-bison.h> +#include <util/pmu-flex.h> #include "parse-events.h" #include "print-events.h" #include "header.h"
Greg Kroah-Hartman
maintainerPATCH 237/285 perf hists browser: Fix the number of entries for e key
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namhyung Kim <[email protected]>
commit f6b8436bede3e80226e8b2100279c4450c73806a upstream.
The 'e' key is to toggle expand/collapse the selected entry only. But the current code has a bug that it only increases the number of entries by 1 in the hierarchy mode so users cannot move under the current entry after the key stroke. This is due to a wrong assumption in the hist_entry__set_folding().
The commit b33f922651011eff ("perf hists browser: Put hist_entry folding logic into single function") factored out the code, but actually it should be handled separately. The hist_browser__set_folding() is to update fold state for each entry so it needs to traverse all (child) entries regardless of the current fold state. So it increases the number of entries by 1.
But the hist_entry__set_folding() only cares the currently selected entry and its all children. So it should count all unfolded child entries. This code is implemented in hist_browser__toggle_fold() already so we can just call it.
--- tools/perf/ui/browsers/hists.c | 58 ++++++++++++++++------------------------- 1 file changed, 24 insertions(+), 34 deletions(-)
tools/perf/ui/browsers/hists.c +24 -34
@@ -407,11 +407,6 @@ static bool hist_browser__selection_has_ return container_of(ms, struct callchain_list, ms)->has_children; } -static bool hist_browser__he_selection_unfolded (struct hist_browser *browser) -{ -return browser->he_selection ? browser->he_selection->unfolded : false; -} -static bool hist_browser__selection_unfolded (struct hist_browser *browser) {struct hist_entry *he = browser->he_selection;
@@ -584,8 +579,8 @@ static int hierarchy_set_folding(structreturn n; } -static void __hist_entry__set_folding (struct hist_entry *he, -struct hist_browser *hb,bool unfold) +static void hist_entry__set_folding (struct hist_entry *he, +struct hist_browser *hb,bool unfold) {hist_entry__init_have_children (he); he->unfolded = unfold ? he->has_children : false;
@@ -603,34 +598,12 @@ static void __hist_entry__set_folding(st he->nr_rows =0 ; } -static void hist_entry__set_folding (struct hist_entry *he, -struct hist_browser *browser,bool unfold) -{ -double percent; - - percent =hist_entry__get_percent_limit (he); -if (he->filtered || percent < browser->min_pcnt) -return ; - -__hist_entry__set_folding (he, browser, unfold); - -if (!he->depth || unfold) - browser->nr_hierarchy_entries++; -if (he->leaf) - browser->nr_callchain_rows += he->nr_rows; -else if (unfold && !hist_entry__has_hierarchy_children (he, browser->min_pcnt)) { - browser->nr_hierarchy_entries++; - he->has_no_entry = true; - he->nr_rows =1 ; - }else - he->has_no_entry = false; -} -static void __hist_browser__set_folding (struct hist_browser *browser,bool unfold) {struct rb_node *nd;struct hist_entry *he; +double percent; nd =rb_first_cached (&browser->hists->entries);while (nd) {
@@ -640,6 +613,21 @@ __hist_browser__set_folding(struct hist_ nd =__rb_hierarchy_next (nd,HMD_FORCE_CHILD );hist_entry__set_folding (he, browser, unfold); + + percent =hist_entry__get_percent_limit (he); +if (he->filtered || percent < browser->min_pcnt) +continue ; + +if (!he->depth || unfold) + browser->nr_hierarchy_entries++; +if (he->leaf) + browser->nr_callchain_rows += he->nr_rows; +else if (unfold && !hist_entry__has_hierarchy_children (he, browser->min_pcnt)) { + browser->nr_hierarchy_entries++; + he->has_no_entry = true; + he->nr_rows =1 ; + }else + he->has_no_entry = false; } }
@@ -659,8 +647,10 @@ static void hist_browser__set_folding_seif (!browser->he_selection)return ; -hist_entry__set_folding (browser->he_selection, browser, unfold); - browser->b.nr_entries =hist_browser__nr_entries (browser); +if (unfold == browser->he_selection->unfolded) +return ; + +hist_browser__toggle_fold (browser); }static void ui_browser__warn_lost_events (struct ui_browser *browser)
@@ -732,8 +722,8 @@ static int hist_browser__handle_hotkey(shist_browser__set_folding (browser, true);break ;case 'e' : -/* Expand the selected entry. */ -hist_browser__set_folding_selected (browser, !hist_browser__he_selection_unfolded (browser)); +/* Toggle expand/collapse the selected entry. */ +hist_browser__toggle_fold (browser);break ;case 'H' : browser->show_headers = !browser->show_headers;
Greg Kroah-Hartman
maintainerPATCH 238/285 drm/amd/display: always switch off ODM before committing more streams
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wenjing Liu <[email protected]>
commit 49a30c3d1a2258fc93cfe6eea8e4951dabadc824 upstream.
ODM power optimization is only supported with single stream. When ODM power optimization is enabled, we might not have enough free pipes for enabling other stream. So when we are committing more than 1 stream we should first switch off ODM power optimization to make room for new stream and then allocating pipe resource for the new stream.
--- drivers/gpu/drm/amd/display/dc/core/dc.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/gpu/drm/amd/display/dc/core/dc.c +5 -5
@@ -2061,12 +2061,12 @@ enum dc_status dc_commit_streams(struct } } -/* Check for case where we are going from odm 2:1 to max -* pipe scenario. For these cases, we will call -* commit_minimal_transition_state() to exit out of odm 2:1 -* first before processing new streams +/* ODM Combine 2:1 power optimization is only applied for single stream +* scenario, it uses extra pipes than needed to reduce power consumption +* We need to switch off this feature to make room for new streams. */ -if (stream_count == dc->res_pool->pipe_count) { +if (stream_count > dc->current_state->stream_count && + dc->current_state->stream_count ==1 ) {for (i =0 ; i < dc->res_pool->pipe_count; i++) { pipe = &dc->current_state->res_ctx.pipe_ctx[i];if (pipe->next_odm_pipe)
Greg Kroah-Hartman
maintainerPATCH 239/285 drm/amd/display: Remove wait while locked
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gabe Teeger <[email protected]>
commit 5a3ccb1400339268c5e3dc1fa044a7f6c7f59a02 upstream.
[Why]
We wait for mpc idle while in a locked state, leading to potential deadlock.
[What]
Move the wait_for_idle call to outside of HW lock. This and a call to wait_drr_doublebuffer_pending_clear are moved added to a new static helper function called wait_for_outstanding_hw_updates, to make the interface clearer.
--- drivers/gpu/drm/amd/display/dc/Makefile | 1 drivers/gpu/drm/amd/display/dc/core/dc.c | 58 ++++++++++++++------- drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c | 11 --- 3 files changed, 42 insertions(+), 28 deletions(-)
drivers/gpu/drm/amd/display/dc/Makefile +1 -0
@@ -78,3 +78,4 @@ DC_EDID += dc_edid_parser.o AMD_DISPLAY_DMUB = $(addprefix $(AMDDALPATH)/dc/,$(DC_DMUB)) AMD_DISPLAY_EDID = $(addprefix $(AMDDALPATH)/dc/,$(DC_EDID)) AMD_DISPLAY_FILES += $(AMD_DISPLAY_DMUB) $(AMD_DISPLAY_EDID) +
drivers/gpu/drm/amd/display/dc/core/dc.c +41 -17
71 lines not on this page · raw message
drivers/gpu/drm/amd/display/dc/dcn20/dcn20_hwseq.c +0 -11
@@ -1580,17 +1580,6 @@ static void dcn20_update_dchubp_dpp( || plane_state->update_flags.bits.global_alpha_change || plane_state->update_flags.bits.per_pixel_alpha_change) {// MPCC inst is equal to pipe index in practice -int mpcc_inst = hubp->inst; -int opp_inst; -int opp_count = dc->res_pool->pipe_count; - -for (opp_inst =0 ; opp_inst < opp_count; opp_inst++) { -if (dc->res_pool->opps[opp_inst]->mpcc_disconnect_pending[mpcc_inst]) { - dc->res_pool->mpc->funcs->wait_for_idle (dc->res_pool->mpc, mpcc_inst); - dc->res_pool->opps[opp_inst]->mpcc_disconnect_pending[mpcc_inst] = false; -break ; - } - } hws->funcs.update_mpcc (dc, pipe_ctx); }
Greg Kroah-Hartman
maintainerPATCH 240/285 drm/amdkfd: Add missing gfx11 MQD manager callbacks
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jay Cornwall <[email protected]>
commit e9dca969b2426702a73719ab9207e43c6d80b581 upstream.
mqd_stride function was introduced in commit 2f77b9a242a2 ("drm/amdkfd: Update MQD management on multi XCC setup") but not assigned for gfx11. Fixes a NULL dereference in debugfs.
--- drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager_v11.c +3 -0
@@ -437,6 +437,7 @@ struct mqd_manager *mqd_manager_init_v11 mqd->is_occupied = kfd_is_occupied_cp; mqd->mqd_size =sizeof (struct v11_compute_mqd ); mqd->get_wave_state = get_wave_state; + mqd->mqd_stride = kfd_mqd_stride;#if defined(CONFIG_DEBUG_FS ) mqd->debugfs_show_mqd = debugfs_show_mqd;#endif
@@ -452,6 +453,7 @@ struct mqd_manager *mqd_manager_init_v11 mqd->destroy_mqd = kfd_destroy_mqd_cp; mqd->is_occupied = kfd_is_occupied_cp; mqd->mqd_size =sizeof (struct v11_compute_mqd ); + mqd->mqd_stride = kfd_mqd_stride;#if defined(CONFIG_DEBUG_FS ) mqd->debugfs_show_mqd = debugfs_show_mqd;#endif
@@ -481,6 +483,7 @@ struct mqd_manager *mqd_manager_init_v11 mqd->destroy_mqd = kfd_destroy_mqd_sdma; mqd->is_occupied = kfd_is_occupied_sdma; mqd->mqd_size =sizeof (struct v11_sdma_mqd ); + mqd->mqd_stride = kfd_mqd_stride;#if defined(CONFIG_DEBUG_FS ) mqd->debugfs_show_mqd = debugfs_show_mqd_sdma;#endif
Greg Kroah-Hartman
maintainerPATCH 241/285 drm/amdgpu: register a dirty framebuffer callback for fbcon
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hamza Mahfooz <[email protected]>
commit 0a611560f53bfd489e33f4a718c915f1a6123d03 upstream.
fbcon requires that we implement &drm_framebuffer_funcs.dirty. Otherwise, the framebuffer might take a while to flush (which would manifest as noticeable lag). However, we can't enable this callback for non-fbcon cases since it may cause too many atomic commits to be made at once. So, implement amdgpu_dirtyfb() and only enable it for fbcon framebuffers (we can use the "struct drm_file file" parameter in the callback to check for this since it is only NULL when called by fbcon, at least in the mainline kernel) on devices that support atomic KMS.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_display.c | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_display.c +25 -1
@@ -38,6 +38,8 @@#include <linux/pci.h> #include <linux/pm_runtime.h> #include <drm/drm_crtc_helper.h> +#include <drm/drm_damage_helper.h> +#include <drm/drm_drv.h> #include <drm/drm_edid.h> #include <drm/drm_fb_helper.h> #include <drm/drm_gem_framebuffer_helper.h>
@@ -529,11 +531,29 @@ bool amdgpu_display_ddc_probe(struct amdreturn true; } +static int amdgpu_dirtyfb (struct drm_framebuffer *fb,struct drm_file *file, +unsigned int flags,unsigned int color, +struct drm_clip_rect *clips,unsigned int num_clips) +{ + +if (file) +return -ENOSYS ; + +return drm_atomic_helper_dirtyfb (fb, file, flags, color, clips, + num_clips); +} +static const struct drm_framebuffer_funcs amdgpu_fb_funcs = { .destroy = drm_gem_fb_destroy, .create_handle = drm_gem_fb_create_handle, }; +static const struct drm_framebuffer_funcs amdgpu_fb_funcs_atomic = { + .destroy = drm_gem_fb_destroy, + .create_handle = drm_gem_fb_create_handle, + .dirty = amdgpu_dirtyfb +}; +uint32_t amdgpu_display_supported_domains (struct amdgpu_device *adev,uint64_t bo_flags) {
@@ -1136,7 +1156,11 @@ static int amdgpu_display_gem_fb_verify_if (ret) goto err; - ret =drm_framebuffer_init (dev, &rfb->base, &amdgpu_fb_funcs); +if (drm_drv_uses_atomic_modeset (dev)) + ret =drm_framebuffer_init (dev, &rfb->base, + &amdgpu_fb_funcs_atomic); +else + ret =drm_framebuffer_init (dev, &rfb->base, &amdgpu_fb_funcs);if (ret) goto err;
Greg Kroah-Hartman
maintainerPATCH 242/285 bpf: fix bpf_probe_read_kernel prototype mismatch
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arnd Bergmann <[email protected]>
[ Upstream commit 6a5a148aaf14747570cc634f9cdfcb0393f5617f ]
bpf_probe_read_kernel() has a __weak definition in core.c and another definition with an incompatible prototype in kernel/trace/bpf_trace.c, when CONFIG_BPF_EVENTS is enabled.
Since the two are incompatible, there cannot be a shared declaration in a header file, but the lack of a prototype causes a W=1 warning:
kernel/bpf/core.c:1638:12: error: no previous prototype for 'bpf_probe_read_kernel' [-Werror=missing-prototypes]
On 32-bit architectures, the local prototype
u64 __weak bpf_probe_read_kernel(void *dst, u32 size, const void *unsafe_ptr)
passes arguments in other registers as the one in bpf_trace.c
BPF_CALL_3(bpf_probe_read_kernel, void *, dst, u32, size,
const void *, unsafe_ptr)
which uses 64-bit arguments in pairs of registers.
As both versions of the function are fairly simple and only really differ in one line, just move them into a header file as an inline function that does not add any overhead for the bpf_trace.c callers and actually avoids a function call for the other one.
--- include/linux/bpf.h | 12 ++++++++++++ kernel/bpf/core.c | 10 ++-------- kernel/trace/bpf_trace.c | 11 ----------- 3 files changed, 14 insertions(+), 19 deletions(-)
include/linux/bpf.h +12 -0
@@ -2619,6 +2619,18 @@ static inline void bpf_dynptr_set_rdonly(struct bpf_dynptr_kern *ptr) }#endif /* CONFIG_BPF_SYSCALL */ +static __always_inline int +bpf_probe_read_kernel_common (void *dst,u32 size,const void *unsafe_ptr) +{ +int ret = -EFAULT ; + +if (IS_ENABLED (CONFIG_BPF_EVENTS )) + ret =copy_from_kernel_nofault (dst, unsafe_ptr, size); +if (unlikely (ret <0 )) +memset (dst,0 , size); +return ret; +} +void __bpf_free_used_btfs (struct bpf_prog_aux *aux,struct btf_mod_pair *used_btfs,u32 len);
kernel/bpf/core.c +2 -8
@@ -1635,12 +1635,6 @@ bool bpf_opcode_in_insntable(u8 code) }#ifndef CONFIG_BPF_JIT_ALWAYS_ON -u64 __weak bpf_probe_read_kernel (void *dst,u32 size,const void *unsafe_ptr) -{ -memset (dst,0 , size); -return -EFAULT ; -} -/** * ___bpf_prog_run - run eBPF program on a given context * @regs: is the array of MAX_BPF_EXT_REG eBPF pseudo-registers
@@ -1931,8 +1925,8 @@ static u64 ___bpf_prog_run(u64 *regs, const struct bpf_insn *insn)DST = *(SIZE *)(unsigned long ) (SRC + insn->off); \CONT ; \ LDX_PROBE_MEM_##SIZEOP: \ -bpf_probe_read_kernel (&DST ,sizeof (SIZE ), \ - (const void *)(long ) (SRC + insn->off)); \ +bpf_probe_read_kernel_common (&DST ,sizeof (SIZE ), \ + (const void *)(long ) (SRC + insn->off)); \DST = *((SIZE *)&DST ); \CONT ;
kernel/trace/bpf_trace.c +0 -11
@@ -223,17 +223,6 @@ const struct bpf_func_proto bpf_probe_read_user_str_proto = { .arg3_type = ARG_ANYTHING, }; -static __always_inline int -bpf_probe_read_kernel_common (void *dst,u32 size,const void *unsafe_ptr) -{ -int ret; - - ret =copy_from_kernel_nofault (dst, unsafe_ptr, size); -if (unlikely (ret <0 )) -memset (dst,0 , size); -return ret; -} - BPF_CALL_3(bpf_probe_read_kernel, void *, dst, u32, size, const void *, unsafe_ptr) {
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 243/285 regulator: raa215300: Change the scope of the variables {clkin_name, xin_name}
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Biju Das <[email protected]>
[ Upstream commit 42a95739c5bc4d7a6e93a43117e9283598ba2287 ]
Change the scope of the variables {clkin_name, xin_name} from global->local to fix the below warning.
drivers/regulator/raa215300.c:42:12: sparse: sparse: symbol 'xin_name' was not declared. Should it be static?
Stable-dep-of: e21ac64e669e ("regulator: raa215300: Fix resource leak in case of error")
--- drivers/regulator/raa215300.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
drivers/regulator/raa215300.c +9 -7
@@ -38,8 +38,6 @@#define RAA215300_REG_BLOCK_EN_RTC_EN BIT(6)#define RAA215300_RTC_DEFAULT_ADDR 0x6f -const char *clkin_name ="clkin" ; -const char *xin_name ="xin" ;static struct clk *clk;static const struct regmap_config raa215300_regmap_config = {
@@ -71,8 +69,10 @@ static int raa215300_clk_present(struct i2c_client *client, const char *name)static int raa215300_i2c_probe (struct i2c_client *client) {struct device *dev = &client->dev; -const char *clk_name = xin_name; +const char *clkin_name ="clkin" ;unsigned int pmic_version, val; +const char *xin_name ="xin" ; +const char *clk_name =NULL ;struct regmap *regmap;int ret;
@@ -114,15 +114,17 @@ static int raa215300_i2c_probe(struct i2c_client *client) ret =raa215300_clk_present (client, xin_name);if (ret <0 ) {return ret; - }else if (!ret) { + }else if (ret) { + clk_name = xin_name; + }else { ret =raa215300_clk_present (client, clkin_name);if (ret <0 )return ret; - - clk_name = clkin_name; +if (ret) + clk_name = clkin_name; } -if (ret) { +if (clk_name) {char *name = pmic_version >=0x12 ?"isl1208" :"raa215300_a0" ;struct device_node *np = client->dev.of_node;u32 addr =RAA215300_RTC_DEFAULT_ADDR ;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 244/285 regulator: raa215300: Fix resource leak in case of error
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Biju Das <[email protected]>
[ Upstream commit e21ac64e669e960688e79bf5babeed63132dac8a ]
The clk_register_clkdev() allocates memory by calling vclkdev_alloc() and this memory is not freed in the error path. Similarly, resources allocated by clk_register_fixed_rate() are not freed in the error path.
Fix these issues by using devm_clk_hw_register_fixed_rate() and devm_clk_hw_register_clkdev().
After this, the static variable clk is not needed. Replace it with local variable hw in probe() and drop calling clk_unregister_fixed_rate() from raa215300_rtc_unregister_device().
--- drivers/regulator/raa215300.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
drivers/regulator/raa215300.c +8 -8
@@ -38,8 +38,6 @@#define RAA215300_REG_BLOCK_EN_RTC_EN BIT(6)#define RAA215300_RTC_DEFAULT_ADDR 0x6f -static struct clk *clk; -static const struct regmap_config raa215300_regmap_config = { .reg_bits =8 , .val_bits =8 ,
@@ -49,10 +47,6 @@ static const struct regmap_config raa215300_regmap_config = {static void raa215300_rtc_unregister_device (void *data) {i2c_unregister_device (data); -if (!clk) { -clk_unregister_fixed_rate (clk); - clk =NULL ; - } }static int raa215300_clk_present (struct i2c_client *client,const char *name)
@@ -130,10 +124,16 @@ static int raa215300_i2c_probe(struct i2c_client *client)u32 addr =RAA215300_RTC_DEFAULT_ADDR ;struct i2c_board_info info = {};struct i2c_client *rtc_client; +struct clk_hw *hw;ssize_t size; - clk =clk_register_fixed_rate (NULL , clk_name,NULL ,0 ,32000 ); -clk_register_clkdev (clk, clk_name,NULL ); + hw =devm_clk_hw_register_fixed_rate (dev, clk_name,NULL ,0 ,32000 ); +if (IS_ERR (hw)) +return PTR_ERR (hw); + + ret =devm_clk_hw_register_clkdev (dev, hw, clk_name,NULL ); +if (ret) +return dev_err_probe (dev, ret,"Failed to initialize clkdev\n" );if (np) {int i;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 245/285 parisc: sba_iommu: Fix build warning if procfs if disabled
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Helge Deller <[email protected]>
[ Upstream commit 6428bc7bd3f35e43c8cb7359cb89d83248d339d2 ]
Clean up the code, e.g. make proc_mckinley_root static, drop the now empty mckinley header file and remove some unneeded ifdefs around procfs functions.
--- arch/parisc/include/asm/mckinley.h | 8 -------- drivers/parisc/sba_iommu.c | 10 ++-------- 2 files changed, 2 insertions(+), 16 deletions(-) delete mode 100644 arch/parisc/include/asm/mckinley.h
arch/parisc/include/asm/mckinley.h deleted +0 -8
@@ -1,8 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef ASM_PARISC_MCKINLEY_H -#define ASM_PARISC_MCKINLEY_H - -/* declared in arch/parisc/kernel/setup.c */ -extern struct proc_dir_entry * proc_mckinley_root; - -#endif /*ASM_PARISC_MCKINLEY_H*/
drivers/parisc/sba_iommu.c +2 -8
@@ -46,8 +46,6 @@#include <linux/module.h> #include <asm/ropes.h> -#include <asm/mckinley.h> /* for proc_mckinley_root */ -#include <asm/runway.h> /* for proc_runway_root */ #include <asm/page.h> /* for PAGE0 */ #include <asm/pdc.h> /* for PDC_MODEL_* */ #include <asm/pdcpat.h> /* for is_pdc_pat() */
@@ -122,7 +120,7 @@ MODULE_PARM_DESC(sba_reserve_agpgart, "Reserve half of IO pdir as AGPGART");#endif static struct proc_dir_entry *proc_runway_root__ro_after_init ; -struct proc_dir_entry *proc_mckinley_root__ro_after_init ; +static struct proc_dir_entry *proc_mckinley_root__ro_after_init ;/************************************ ** SBA register read and write support
@@ -1899,9 +1897,7 @@ static int __init sba_driver_callback(struct parisc_device *dev)int i;char *version;void __iomem *sba_addr =ioremap (dev->hpa.start,SBA_FUNC_SIZE ); -#ifdef CONFIG_PROC_FS -struct proc_dir_entry *root; -#endif +struct proc_dir_entry *root__maybe_unused ;sba_dump_ranges (sba_addr);
@@ -1967,7 +1963,6 @@ static int __init sba_driver_callback(struct parisc_device *dev) hppa_dma_ops = &sba_ops; -#ifdef CONFIG_PROC_FS switch (dev->id.hversion) {case PLUTO_MCKINLEY_PORT :if (!proc_mckinley_root)
@@ -1985,7 +1980,6 @@ static int __init sba_driver_callback(struct parisc_device *dev)proc_create_single ("sba_iommu" ,0 , root, sba_proc_info);proc_create_single ("sba_iommu-bitmap" ,0 , root, sba_proc_bitmap_info); -#endif return 0 ; }
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 246/285 kunit: Fix wild-memory-access bug in kunit_free_suite_set()
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jinjie Ruan <[email protected]>
[ Upstream commit 2810c1e99867a811e631dd24e63e6c1e3b78a59d ]
Inject fault while probing kunit-example-test.ko, if kstrdup() fails in mod_sysfs_setup() in load_module(), the mod->state will switch from MODULE_STATE_COMING to MODULE_STATE_GOING instead of from MODULE_STATE_LIVE to MODULE_STATE_GOING, so only kunit_module_exit() will be called without kunit_module_init(), and the mod->kunit_suites is no set correctly and the free in kunit_free_suite_set() will cause below wild-memory-access bug.
The mod->state state machine when load_module() succeeds:
MODULE_STATE_UNFORMED ---> MODULE_STATE_COMING ---> MODULE_STATE_LIVE
^ | | | delete_module +---------------- MODULE_STATE_GOING <---------+
The mod->state state machine when load_module() fails at mod_sysfs_setup():
MODULE_STATE_UNFORMED ---> MODULE_STATE_COMING ---> MODULE_STATE_GOING
^ | | | +-----------------------------------------------+
Call kunit_module_init() at MODULE_STATE_COMING state to fix the issue because MODULE_STATE_LIVE is transformed from it.
Unable to handle kernel paging request at virtual address ffffff341e942a88 KASAN: maybe wild-memory-access in range [0x0003f9a0f4a15440-0x0003f9a0f4a15447] Mem abort info: ESR = 0x0000000096000004 EC = 0x25: DABT (current EL), IL = 32 bits SET = 0, FnV = 0 EA = 0, S1PTW = 0 FSC = 0x04: level 0 translation fault Data abort info: ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000 CM = 0, WnR = 0, TnD = 0, TagAccess = 0 GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0 swapper pgtable: 4k pages, 48-bit VAs, pgdp=00000000441ea000 [ffffff341e942a88] pgd=0000000000000000, p4d=0000000000000000 Internal error: Oops: 0000000096000004 [#1] PREEMPT SMP Modules linked in: kunit_example_test(-) cfg80211 rfkill 8021q garp mrp stp llc ipv6 [last unloaded: kunit_example_test] CPU: 3 PID: 2035 Comm: modprobe Tainted: G W N 6.5.0-next-20230828+ #136 Hardware name: linux,dummy-virt (DT) pstate: a0000005 (NzCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : kfree+0x2c/0x70 lr : kunit_free_suite_set+0xcc/0x13c sp : ffff8000829b75b0 x29: ffff8000829b75b0 x28: ffff8000829b7b90 x27: 0000000000000000 x26: dfff800000000000 x25: ffffcd07c82a7280 x24: ffffcd07a50ab300 x23: ffffcd07a50ab2e8 x22: 1ffff00010536ec0 x21: dfff800000000000 x20: ffffcd07a50ab2f0 x19: ffffcd07a50ab2f0 x18: 0000000000000000 x17: 0000000000000000 x16: 0000000000000000 x15: ffffcd07c24b6764 x14: ffffcd07c24b63c0 x13: ffffcd07c4cebb94 x12: ffff700010536ec7 x11: 1ffff00010536ec6 x10: ffff700010536ec6 x9 : dfff800000000000 x8 : 00008fffefac913a x7 : 0000000041b58ab3 x6 : 0000000000000000 x5 : 1ffff00010536ec5 x4 : ffff8000829b7628 x3 : dfff800000000000 x2 : ffffff341e942a80 x1 : ffffcd07a50aa000 x0 : fffffc0000000000 Call trace: kfree+0x2c/0x70 kunit_free_suite_set+0xcc/0x13c kunit_module_notify+0xd8/0x360 blocking_notifier_call_chain+0xc4/0x128 load_module+0x382c/0x44a4 init_module_from_file+0xd4/0x128 idempotent_init_module+0x2c8/0x524 __arm64_sys_finit_module+0xac/0x100 invoke_syscall+0x6c/0x258 el0_svc_common.constprop.0+0x160/0x22c do_el0_svc+0x44/0x5c el0_svc+0x38/0x78 el0t_64_sync_handler+0x13c/0x158 el0t_64_sync+0x190/0x194 Code: aa0003e1 b25657e0 d34cfc42 8b021802 (f9400440) ---[ end trace 0000000000000000 ]--- Kernel panic - not syncing: Oops: Fatal exception SMP: stopping secondary CPUs Kernel Offset: 0x4d0742200000 from 0xffff800080000000 PHYS_OFFSET: 0xffffee43c0000000 CPU features: 0x88000203,3c020000,1000421b Memory Limit: none Rebooting in 1 seconds..
--- lib/kunit/test.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
lib/kunit/test.c +2 -1
@@ -744,12 +744,13 @@ static int kunit_module_notify(struct notifier_block *nb, unsigned long val,switch (val) {case MODULE_STATE_LIVE : -kunit_module_init (mod);break ;case MODULE_STATE_GOING :kunit_module_exit (mod);break ;case MODULE_STATE_COMING : +kunit_module_init (mod); +break ;case MODULE_STATE_UNFORMED :break ; }
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 247/285 net: ipv4: fix one memleak in __inet_del_ifa()
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Liu Jian <[email protected]>
[ Upstream commit ac28b1ec6135649b5d78b028e47264cb3ebca5ea ]
I got the below warning when do fuzzing test:unregister_netdevice: waiting for bond0 to become free. Usage count = 2
It can be repoduced via:
ip link add bond0 type bond
sysctl -w net.ipv4.conf.bond0.promote_secondaries=1 ip addr add 4.117.174.103/0 scope 0x40 dev bond0
ip addr add 192.168.100.111/255.255.255.254 scope 0 dev bond0 ip addr add 0.0.0.4/0 scope 0x40 secondary dev bond0 ip addr del 4.117.174.103/0 scope 0x40 dev bond0
ip link delete bond0 type bond
In this reproduction test case, an incorrect 'last_prim' is found in __inet_del_ifa(), as a result, the secondary address(0.0.0.4/0 scope 0x40) is lost. The memory of the secondary address is leaked and the reference of in_device and net_device is leaked.
Fix this problem:
Look for 'last_prim' starting at location of the deleted IP and inserting the promoted IP into the location of 'last_prim'.
--- net/ipv4/devinet.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
net/ipv4/devinet.c +5 -5
@@ -355,14 +355,14 @@ static void __inet_del_ifa(struct in_device *in_dev, {struct in_ifaddr *promote =NULL ;struct in_ifaddr *ifa, *ifa1; -struct in_ifaddr *last_prim; +struct in_ifaddr __rcu **last_prim;struct in_ifaddr *prev_prom =NULL ;int do_promote =IN_DEV_PROMOTE_SECONDARIES (in_dev);ASSERT_RTNL (); ifa1 =rtnl_dereference (*ifap); - last_prim =rtnl_dereference (in_dev->ifa_list); + last_prim = ifap;if (in_dev->dead) goto no_promotions;
@@ -376,7 +376,7 @@ static void __inet_del_ifa(struct in_device *in_dev,while ((ifa =rtnl_dereference (*ifap1)) !=NULL ) {if (!(ifa->ifa_flags &IFA_F_SECONDARY ) && ifa1->ifa_scope <= ifa->ifa_scope) - last_prim = ifa; + last_prim = &ifa->ifa_next; if (!(ifa->ifa_flags & IFA_F_SECONDARY) || ifa1->ifa_mask != ifa->ifa_mask ||
@@ -440,9 +440,9 @@ static void __inet_del_ifa(struct in_device *in_dev,rcu_assign_pointer (prev_prom->ifa_next, next_sec); - last_sec =rtnl_dereference (last_prim->ifa_next); + last_sec =rtnl_dereference (*last_prim);rcu_assign_pointer (promote->ifa_next, last_sec); -rcu_assign_pointer (last_prim->ifa_next, promote); +rcu_assign_pointer (*last_prim, promote); } promote->ifa_flags &= ~IFA_F_SECONDARY ;
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 248/285 kselftest/runner.sh: Propagate SIGTERM to runner child
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Björn Töpel <[email protected]>
[ Upstream commit 9616cb34b08ec86642b162eae75c5a7ca8debe3c ]
Timeouts in kselftest are done using the "timeout" command with the "--foreground" option. Without the "foreground" option, it is not possible for a user to cancel the runner using SIGINT, because the signal is not propagated to timeout which is running in a different process group. The "forground" options places the timeout in the same process group as its parent, but only sends the SIGTERM (on timeout) signal to the forked process. Unfortunately, this does not play nice with all kselftests, e.g. "net:fcnal-test.sh", where the child processes will linger because timeout does not send SIGTERM to the group.
Some users have noted these hangs [1].
Fix this by nesting the timeout with an additional timeout without the foreground option.
--- tools/testing/selftests/kselftest/runner.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
tools/testing/selftests/kselftest/runner.sh +2 -1
@@ -36,7 +36,8 @@ tap_timeout() { # Make sure tests will time out if utility is available. if [ -x /usr/bin/timeout ] ; then - /usr/bin/timeout --foreground "$kselftest_timeout" $1 + /usr/bin/timeout --foreground "$kselftest_timeout" \ + /usr/bin/timeout "$kselftest_timeout" $1 else $1 fi
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 249/285 selftests: Keep symlinks, when possible
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Björn Töpel <[email protected]>
[ Upstream commit 3f3f384139ed147c71e1d770accf610133d5309b ]
When kselftest is built/installed with the 'gen_tar' target, rsync is used for the installation step to copy files. Extra care is needed for tests that have symlinks. Commit ae108c48b5d2 ("selftests: net: Fix cross-tree inclusion of scripts") added '-L' (transform symlink into referent file/dir) to rsync, to fix dangling links. However, that broke some tests where the symlink (being a symlink) is part of the test (e.g. exec:execveat).
Use rsync's '--copy-unsafe-links' that does right thing.
--- tools/testing/selftests/lib.mk | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
tools/testing/selftests/lib.mk +2 -2
@@ -106,7 +106,7 @@ endef run_tests: all ifdef building_out_of_srctree @if [ "X$(TEST_PROGS)$(TEST_PROGS_EXTENDED)$(TEST_FILES)" != "X" ]; then \ - rsync -aLq $(TEST_PROGS) $(TEST_PROGS_EXTENDED) $(TEST_FILES) $(OUTPUT); \ + rsync -aq --copy-unsafe-links $(TEST_PROGS) $(TEST_PROGS_EXTENDED) $(TEST_FILES) $(OUTPUT); \ fi @if [ "X$(TEST_PROGS)" != "X" ]; then \ $(call RUN_TESTS, $(TEST_GEN_PROGS) $(TEST_CUSTOM_PROGS) \
@@ -120,7 +120,7 @@ endif define INSTALL_SINGLE_RULE $(if $(INSTALL_LIST),@mkdir -p $(INSTALL_PATH)) - $(if $(INSTALL_LIST),rsync -aL $(INSTALL_LIST) $(INSTALL_PATH)/) + $(if $(INSTALL_LIST),rsync -a --copy-unsafe-links $(INSTALL_LIST) $(INSTALL_PATH)/) endef define INSTALL_RULE
Signature · 1 line
2.40.1
Greg Kroah-Hartman
maintainerPATCH 250/285 selftests/ftrace: Fix dependencies for some of the synthetic event tests
In reply to Greg Kroah-Hartman6.5-stable review patch. If anyone has any objections, please let me know.
------------------
From: Naveen N Rao <[email protected]>
[ Upstream commit 145036f88d693d7ef3aa8537a4b1aa22f8764647 ]
Commit b81a3a100cca1b ("tracing/histogram: Add simple tests for stacktrace usage of synthetic events") changed the output text in tracefs README, but missed updating some of the dependencies specified in selftests. This causes some of the tests to exit as unsupported.
Fix this by changing the grep pattern. Since we want these tests to work on older kernels, match only against the common last part of the pattern.
--- .../trigger/inter-event/trigger-synthetic-event-dynstring.tc | 2 +- .../inter-event/trigger-synthetic_event_syntax_errors.tc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-synthetic-event-dynstring.tc +1 -1
@@ -1,7 +1,7 @@ #!/bin/sh # SPDX-License-Identifier: GPL-2.0 # description: event trigger - test inter-event histogram trigger trace action with dynamic string param -# requires: set_event synthetic_events events/sched/sched_process_exec/hist "char name[]' >> synthetic_events":README ping:program +# requires: set_event synthetic_events events/sched/sched_process_exec/hist "' >> synthetic_events":README ping:program fail() { #msg echo $1
tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-synthetic_event_syntax_errors.tc +1 -1
@@ -1,7 +1,7 @@ #!/bin/sh # SPDX-License-Identifier: GPL-2.0 # description: event trigger - test synthetic_events syntax parser errors -# requires: synthetic_events error_log "char name[]' >> synthetic_events":README +# requires: synthetic_events error_log "' >> synthetic_events":README check_error() { # command-with-error-pos-by-^ ftrace_errlog_check 'synthetic_events' "$1" 'synthetic_events'
Signature · 1 line
2.40.1