3.16.61-rc1 review
Subsystems (10)
PATCH 304/366 netlink: Do not subscribe to non-existent groups
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Safonov <[email protected]>
commit 7acf9d4237c46894e0fa0492dd96314a41742e84 upstream.
Make ABI more strict about subscribing to group > ngroups. Code doesn't check for that and it looks bogus.
(one can subscribe to non-existing group)
Still, it's possible to bind() to all possible groups with (-1)
--- net/netlink/af_netlink.c | 1 + 1 file changed, 1 insertion(+)
net/netlink/af_netlink.c +1 -0
@@ -927,6 +927,7 @@ static int netlink_bind(struct socket *sif (err)return err; } + groups &= (1UL << nlk->ngroups) -1 ;if (nlk->portid)if (nladdr->nl_pid != nlk->portid)
PATCH 305/366 netlink: Don't shift with UB on nlk->ngroups
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Safonov <[email protected]>
commit 61f4b23769f0cc72ae62c9a81cf08f0397d40da8 upstream.
On i386 nlk->ngroups might be 32 or 0. Which leads to UB, resulting in hang during boot.
Check for 0 ngroups and use (unsigned long long) as a type to shift.
--- net/netlink/af_netlink.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
net/netlink/af_netlink.c +5 -1
@@ -927,7 +927,11 @@ static int netlink_bind(struct socket *sif (err)return err; } - groups &= (1UL << nlk->ngroups) -1 ; + +if (nlk->ngroups ==0 ) + groups =0 ; +else + groups &= (1ULL << nlk->ngroups) -1 ;if (nlk->portid)if (nladdr->nl_pid != nlk->portid)
PATCH 306/366 squashfs: more metadata hardening
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Linus Torvalds <[email protected]>
commit d512584780d3e6a7cacb2f482834849453d444a1 upstream.
Anatoly reports another squashfs fuzzing issue, where the decompression parameters themselves are in a compressed block.
This causes squashfs_read_data() to be called in order to read the decompression options before the decompression stream having been set up, making squashfs go sideways.
--- fs/squashfs/block.c | 2 ++ 1 file changed, 2 insertions(+)
fs/squashfs/block.c +2 -0
@@ -166,6 +166,8 @@ int squashfs_read_data(struct super_bloc }if (compressed) { +if (!msblk->stream) + goto read_failure; length =squashfs_decompress (msblk, bh, b, offset, length, output);if (length <0 )
PATCH 307/366 nohz: Fix local_timer_softirq_pending()
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Anna-Maria Gleixner <[email protected]>
commit 80d20d35af1edd632a5e7a3b9c0ab7ceff92769e upstream.
local_timer_softirq_pending() checks whether the timer softirq is pending with: local_softirq_pending() & TIMER_SOFTIRQ.
This is wrong because TIMER_SOFTIRQ is the softirq number and not a bitmask. So the test checks for the wrong bit.
Use BIT(TIMER_SOFTIRQ) instead.
--- kernel/time/tick-sched.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/time/tick-sched.c +1 -1
@@ -529,7 +529,7 @@ EXPORT_SYMBOL_GPL(get_cpu_iowait_time_usstatic inline bool local_timer_softirq_pending (void ) { -return local_softirq_pending () &TIMER_SOFTIRQ ; +return local_softirq_pending () &BIT (TIMER_SOFTIRQ ); } static ktime_t tick_nohz_stop_sched_tick(struct tick_sched *ts,
PATCH 308/366 scsi: sr: Avoid that opening a CD-ROM hangs with runtime power management enabled
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Bart Van Assche <[email protected]>
commit 1214fd7b497400d200e3f4e64e2338b303a20949 upstream.
Surround scsi_execute() calls with scsi_autopm_get_device() and scsi_autopm_put_device(). Note: removing sr_mutex protection from the scsi_cd_get() and scsi_cd_put() calls is safe because the purpose of sr_mutex is to serialize cdrom_*() calls.
This patch avoids that complaints similar to the following appear in the kernel log if runtime power management is enabled:
INFO: task systemd-udevd:650 blocked for more than 120 seconds.
Not tainted 4.18.0-rc7-dbg+ #1
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
systemd-udevd D28176 650 513 0x00000104
Call Trace:
__schedule+0x444/0xfe0
schedule+0x4e/0xe0
schedule_preempt_disabled+0x18/0x30
__mutex_lock+0x41c/0xc70
mutex_lock_nested+0x1b/0x20
__blkdev_get+0x106/0x970
blkdev_get+0x22c/0x5a0
blkdev_open+0xe9/0x100
do_dentry_open.isra.19+0x33e/0x570
vfs_open+0x7c/0xd0
path_openat+0x6e3/0x1120
do_filp_open+0x11c/0x1c0
do_sys_open+0x208/0x2d0
__x64_sys_openat+0x59/0x70
do_syscall_64+0x77/0x230
entry_SYSCALL_64_after_hwframe+0x49/0xbe[bwh: Backported to 3.16:
- Update one extra "goto out" in sr_block_ioctl() and delete the unused label
- Adjust context]
---
drivers/scsi/sr.c +23 -10
@@ -521,16 +521,25 @@ static int sr_init_command(struct scsi_cstatic int sr_block_open (struct block_device *bdev,fmode_t mode) {struct scsi_cd *cd; +struct scsi_device *sdev;int ret = -ENXIO ; -mutex_lock (&sr_mutex); cd =scsi_cd_get (bdev->bd_disk); -if (cd) { - ret =cdrom_open (&cd->cdi, bdev, mode); -if (ret) -scsi_cd_put (cd); - } +if (!cd) + goto out; + + sdev = cd->device; +scsi_autopm_get_device (sdev); + +mutex_lock (&sr_mutex); + ret =cdrom_open (&cd->cdi, bdev, mode);mutex_unlock (&sr_mutex); + +scsi_autopm_put_device (sdev); +if (ret) +scsi_cd_put (cd); + +out:return ret; }
@@ -553,6 +562,8 @@ static int sr_block_ioctl(struct block_dmutex_lock (&sr_mutex); +scsi_autopm_get_device (sdev); +/* * Send SCSI addressing ioctls directly to mid level, send other * ioctls to cdrom/block level.
@@ -561,12 +572,12 @@ static int sr_block_ioctl(struct block_dcase SCSI_IOCTL_GET_IDLUN :case SCSI_IOCTL_GET_BUS_NUMBER : ret =scsi_ioctl (sdev, cmd, argp); - goto out; + goto put; } ret =cdrom_ioctl (&cd->cdi, bdev, mode, cmd, arg);if (ret != -ENOSYS ) - goto out; + goto put;/* * ENODEV means that we didn't recognise the ioctl, or that we
@@ -577,10 +588,12 @@ static int sr_block_ioctl(struct block_d ret =scsi_nonblockable_ioctl (sdev, cmd, argp, (mode &FMODE_NDELAY ) !=0 );if (ret != -ENODEV ) - goto out; + goto put; ret =scsi_ioctl (sdev, cmd, argp); -out: +put: +scsi_autopm_put_device (sdev); +mutex_unlock (&sr_mutex);return ret; }
PATCH 309/366 l2tp: fix missing refcount drop in pppol2tp_tunnel_ioctl()
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Guillaume Nault <[email protected]>
commit f664e37dcc525768280cb94321424a09beb1c992 upstream.
If 'session' is not NULL and is not a PPP pseudo-wire, then we fail to drop the reference taken by l2tp_session_get().
--- net/l2tp/l2tp_ppp.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
net/l2tp/l2tp_ppp.c +11 -4
@@ -1231,15 +1231,22 @@ static int pppol2tp_tunnel_ioctl(structl2tp_session_get (sock_net (sk), tunnel, stats.session_id, true); -if (session && session->pwtype ==L2TP_PWTYPE_PPP ) { - err =pppol2tp_session_ioctl (session, cmd, - arg); +if (!session) { + err = -EBADR ; +break ; + } +if (session->pwtype !=L2TP_PWTYPE_PPP ) {if (session->deref) session->deref (session);l2tp_session_dec_refcount (session); - }else { err = -EBADR ; +break ; } + + err =pppol2tp_session_ioctl (session, cmd, arg); +if (session->deref) + session->deref (session); +l2tp_session_dec_refcount (session);break ; }#ifdef CONFIG_XFRM
PATCH 310/366 netlink: Don't shift on 64 for ngroups
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Safonov <[email protected]>
commit 91874ecf32e41b5d86a4cb9d60e0bee50d828058 upstream.
It's legal to have 64 groups for netlink_sock.
As user-supplied nladdr->nl_groups is __u32, it's possible to subscribe only to first 32 groups.
The check for correctness of .bind() userspace supplied parameter is done by applying mask made from ngroups shift. Which broke Android as they have 64 groups and the shift for mask resulted in an overflow.
--- net/netlink/af_netlink.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
net/netlink/af_netlink.c +2 -2
@@ -930,8 +930,8 @@ static int netlink_bind(struct socket *sif (nlk->ngroups ==0 ) groups =0 ; -else - groups &= (1ULL << nlk->ngroups) -1 ; +else if (nlk->ngroups <8 *sizeof (groups)) + groups &= (1UL << nlk->ngroups) -1 ;if (nlk->portid)if (nladdr->nl_pid != nlk->portid)
PATCH 311/366 root dentries need RCU-delayed freeing
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro <[email protected]>
commit 90bad5e05bcdb0308cfa3d3a60f5c0b9c8e2efb3 upstream.
Since mountpoint crossing can happen without leaving lazy mode, root dentries do need the same protection against having their memory freed without RCU delay as everything else in the tree.
It's partially hidden by RCU delay between detaching from the mount tree and dropping the vfsmount reference, but the starting point of pathwalk can be on an already detached mount, in which case umount-caused RCU delay has already passed by the time the lazy pathwalk grabs rcu_read_lock(). If the starting point happens to be at the root of that vfsmount *and* that vfsmount covers the entire filesystem, we get trouble.
--- fs/dcache.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
fs/dcache.c +4 -2
@@ -1812,10 +1812,12 @@ struct dentry *d_make_root(struct inodestatic const struct qstr name =QSTR_INIT ("/" ,1 ); res =__d_alloc (root_inode->i_sb, &name); -if (res) +if (res) { + res->d_flags |=DCACHE_RCUACCESS ;d_instantiate (res, root_inode); -else + }else {iput (root_inode); + } }return res; }
PATCH 312/366 packet: refine ring v3 block size test to hold one frame
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Willem de Bruijn <[email protected]>
commit 4576cd469d980317c4edd9173f8b694aa71ea3a3 upstream.
TPACKET_V3 stores variable length frames in fixed length blocks. Blocks must be able to store a block header, optional private space and at least one minimum sized frame.
Frames, even for a zero snaplen packet, store metadata headers and optional reserved space.
In the block size bounds check, ensure that the frame of the chosen configuration fits. This includes sockaddr_ll and optional tp_reserve.
Syzbot was able to construct a ring with insuffient room for the sockaddr_ll in the header of a zero-length frame, triggering an out-of-bounds write in dev_parse_header.
Convert the comparison to less than, as zero is a valid snap len. This matches the test for minimum tp_frame_size immediately below.
--- net/packet/af_packet.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
net/packet/af_packet.c +6 -4
@@ -3874,6 +3874,8 @@ static int packet_set_ring(struct sock * }if (req->tp_block_nr) { +unsigned int min_frame_size; +/* Sanity tests and some calculations */ err = -EBUSY ;if (unlikely (rb->pg_vec))
@@ -3896,12 +3898,12 @@ static int packet_set_ring(struct sock * goto out;if (unlikely (req->tp_block_size & (PAGE_SIZE -1 ))) goto out; + min_frame_size = po->tp_hdrlen + po->tp_reserve;if (po->tp_version >=TPACKET_V3 && - req->tp_block_size <= -BLK_PLUS_PRIV ((u64 )req_u->req3.tp_sizeof_priv) +sizeof (struct tpacket3_hdr )) + req->tp_block_size < +BLK_PLUS_PRIV ((u64 )req_u->req3.tp_sizeof_priv) + min_frame_size) goto out; -if (unlikely (req->tp_frame_size < po->tp_hdrlen + - po->tp_reserve)) +if (unlikely (req->tp_frame_size < min_frame_size)) goto out;if (unlikely (req->tp_frame_size & (TPACKET_ALIGNMENT -1 ))) goto out;
PATCH 313/366 vsock: split dwork to avoid reinitializations
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Cong Wang <[email protected]>
commit 455f05ecd2b219e9a216050796d30c830d9bc393 upstream.
syzbot reported that we reinitialize an active delayed work in vsock_stream_connect():
ODEBUG: init active (active state 0) object type: timer_list hint: delayed_work_timer_fn+0x0/0x90 kernel/workqueue.c:1414 WARNING: CPU: 1 PID: 11518 at lib/debugobjects.c:329 debug_print_object+0x16a/0x210 lib/debugobjects.c:326
The pattern is apparently wrong, we should only initialize the dealyed work once and could repeatly schedule it. So we have to move out the initializations to allocation side. And to avoid confusion, we can split the shared dwork into two, instead of re-using the same one.
--- include/net/af_vsock.h | 4 ++-- net/vmw_vsock/af_vsock.c | 15 ++++++++------- net/vmw_vsock/vmci_transport.c | 3 +-- 3 files changed, 11 insertions(+), 11 deletions(-)
include/net/af_vsock.h +2 -2
@@ -59,7 +59,8 @@ struct vsock_sock {struct list_head pending_links;struct list_head accept_queue;bool rejected; -struct delayed_work dwork; +struct delayed_work connect_work; +struct delayed_work pending_work;u32 peer_shutdown;bool sent_request;bool ignore_connecting_rst;
@@ -70,7 +71,6 @@ struct vsock_sock {s64 vsock_stream_has_data (struct vsock_sock *vsk);s64 vsock_stream_has_space (struct vsock_sock *vsk); -void vsock_pending_work (struct work_struct *work); struct sock *__vsock_create(struct net *net, struct socket *sock, struct sock *parent,
net/vmw_vsock/af_vsock.c +8 -7
@@ -431,14 +431,14 @@ static int vsock_send_shutdown(struct soreturn transport->shutdown (vsock_sk (sk), mode); } -void vsock_pending_work (struct work_struct *work) +static void vsock_pending_work (struct work_struct *work) {struct sock *sk;struct sock *listener;struct vsock_sock *vsk;bool cleanup; - vsk = container_of(work, struct vsock_sock, dwork.work); + vsk = container_of(work, struct vsock_sock, pending_work.work); sk =sk_vsock (vsk); listener = vsk->listener; cleanup = true;
@@ -478,7 +478,6 @@ out:sock_put (sk);sock_put (listener); } -EXPORT_SYMBOL_GPL (vsock_pending_work);/**** SOCKET OPERATIONS ****/
@@ -577,6 +576,8 @@ static int __vsock_bind(struct sock *sk,return retval; } +static void vsock_connect_timeout (struct work_struct *work); + struct sock *__vsock_create(struct net *net, struct socket *sock, struct sock *parent,
@@ -618,6 +619,8 @@ struct sock *__vsock_create(struct net * vsk->sent_request = false; vsk->ignore_connecting_rst = false; vsk->peer_shutdown =0 ; +INIT_DELAYED_WORK (&vsk->connect_work, vsock_connect_timeout); +INIT_DELAYED_WORK (&vsk->pending_work, vsock_pending_work); psk = parent ?vsock_sk (parent) :NULL ;if (parent) {
@@ -1095,7 +1098,7 @@ static void vsock_connect_timeout(structstruct sock *sk;struct vsock_sock *vsk; - vsk = container_of(work, struct vsock_sock, dwork.work); + vsk = container_of(work, struct vsock_sock, connect_work.work); sk =sk_vsock (vsk);lock_sock (sk);
@@ -1196,9 +1199,7 @@ static int vsock_stream_connect(struct s* timeout fires. */ sock_hold (sk); -INIT_DELAYED_WORK (&vsk->dwork, - vsock_connect_timeout); -schedule_delayed_work (&vsk->dwork, timeout); +schedule_delayed_work (&vsk->connect_work, timeout);/* Skip ahead to preserve error code set above. */ goto out_wait;
net/vmw_vsock/vmci_transport.c +1 -2
@@ -1101,8 +1101,7 @@ static int vmci_transport_recv_listen(st vpending->listener = sk;sock_hold (sk);sock_hold (pending); -INIT_DELAYED_WORK (&vpending->dwork, vsock_pending_work); -schedule_delayed_work (&vpending->dwork,HZ ); +schedule_delayed_work (&vpending->pending_work,HZ ); out:return err;
PATCH 314/366 dccp: fix undefined behavior with 'cwnd' shift in ccid2_cwnd_restart()
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Alexey Kodanev <[email protected]>
commit 61ef4b07fcdc30535889990cf4229766502561cf upstream.
The shift of 'cwnd' with '(now - hc->tx_lsndtime) / hc->tx_rto' value can lead to undefined behavior [1].
In order to fix this use a gradual shift of the window with a 'while' loop, similar to what tcp_cwnd_restart() is doing.
When comparing delta and RTO there is a minor difference between TCP and DCCP, the last one also invokes dccp_cwnd_restart() and reduces 'cwnd' if delta equals RTO. That case is preserved in this change.
[1]:
[40850.963623] UBSAN: Undefined behaviour in net/dccp/ccids/ccid2.c:237:7 [40851.043858] shift exponent 67 is too large for 32-bit type 'unsigned int' [40851.127163] CPU: 3 PID: 15940 Comm: netstress Tainted: G W E 4.18.0-rc7.x86_64 #1 ... [40851.377176] Call Trace: [40851.408503] dump_stack+0xf1/0x17b [40851.451331] ? show_regs_print_info+0x5/0x5 [40851.503555] ubsan_epilogue+0x9/0x7c [40851.548363] __ubsan_handle_shift_out_of_bounds+0x25b/0x2b4 [40851.617109] ? __ubsan_handle_load_invalid_value+0x18f/0x18f [40851.686796] ? xfrm4_output_finish+0x80/0x80 [40851.739827] ? lock_downgrade+0x6d0/0x6d0 [40851.789744] ? xfrm4_prepare_output+0x160/0x160 [40851.845912] ? ip_queue_xmit+0x810/0x1db0 [40851.895845] ? ccid2_hc_tx_packet_sent+0xd36/0x10a0 [dccp] [40851.963530] ccid2_hc_tx_packet_sent+0xd36/0x10a0 [dccp] [40852.029063] dccp_xmit_packet+0x1d3/0x720 [dccp] [40852.086254] dccp_write_xmit+0x116/0x1d0 [dccp] [40852.142412] dccp_sendmsg+0x428/0xb20 [dccp] [40852.195454] ? inet_dccp_listen+0x200/0x200 [dccp] [40852.254833] ? sched_clock+0x5/0x10 [40852.298508] ? sched_clock+0x5/0x10 [40852.342194] ? inet_create+0xdf0/0xdf0 [40852.388988] sock_sendmsg+0xd9/0x160
...
--- net/dccp/ccids/ccid2.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
net/dccp/ccids/ccid2.c +4 -2
@@ -228,14 +228,16 @@ static void ccid2_cwnd_restart(struct sostruct ccid2_hc_tx_sock *hc =ccid2_hc_tx_sk (sk);u32 cwnd = hc->tx_cwnd, restart_cwnd, iwnd =rfc3390_bytes_to_packets (dccp_sk (sk)->dccps_mss_cache); +s32 delta = now - hc->tx_lsndtime; hc->tx_ssthresh =max (hc->tx_ssthresh, (cwnd >>1 ) + (cwnd >>2 ));/* don't reduce cwnd below the initial window (IW) */ restart_cwnd =min (cwnd, iwnd); - cwnd >>= (now - hc->tx_lsndtime) / hc->tx_rto; - hc->tx_cwnd =max (cwnd, restart_cwnd); +while ((delta -= hc->tx_rto) >=0 && cwnd > restart_cwnd) + cwnd >>=1 ; + hc->tx_cwnd =max (cwnd, restart_cwnd); hc->tx_cwnd_stamp = now; hc->tx_cwnd_used =0 ;
PATCH 315/366 fix mntput/mntput race
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro <[email protected]>
commit 9ea0a46ca2c318fcc449c1e6b62a7230a17888f1 upstream.
mntput_no_expire() does the calculation of total refcount under mount_lock; unfortunately, the decrement (as well as all increments) are done outside of it, leading to false positives in the "are we dropping the last reference" test. Consider the following situation:
* mnt is a lazy-umounted mount, kept alive by two opened files. One
of those files gets closed. Total refcount of mnt is 2. On CPU 42 mntput(mnt) (called from __fput()) drops one reference, decrementing component
* After it has looked at component #0, the process on CPU 0 doesmntget(), incrementing component #0, gets preempted and gets to run again - on CPU 69. There it does mntput(), which drops the reference (component #69) and proceeds to spin on mount_lock.
* On CPU 42 our first mntput() finishes counting. It observes the
decrement of component #69, but not the increment of component #0. As the result, the total it gets is not 1 as it should've been - it's 0. At which point we decide that vfsmount needs to be killed and proceed to free it and shut the filesystem down. However, there's still another opened file on that filesystem, with reference to (now freed) vfsmount, etc. and we are screwed.
It's not a wide race, but it can be reproduced with artificial slowdown of the mnt_get_count() loop, and it should be easier to hit on SMP KVM setups.
Fix consists of moving the refcount decrement under mount_lock; the tricky part is that we want (and can) keep the fast case (i.e. mount that still has non-NULL ->mnt_ns) entirely out of mount_lock. All places that zero mnt->mnt_ns are dropping some reference to mnt and they call synchronize_rcu() before that mntput(). IOW, if mntput() observes (under rcu_read_lock()) a non-NULL ->mnt_ns, it is guaranteed that there is another reference yet to be dropped.
--- fs/namespace.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
fs/namespace.c +12 -2
@@ -969,12 +969,22 @@ static void mntput_no_expire(struct moun { put_again:rcu_read_lock (); -mnt_add_count (mnt,-1 ); -if (likely (mnt->mnt_ns)) {/* shouldn't be the last one */ +if (likely (ACCESS_ONCE (mnt->mnt_ns))) { +/* +* Since we don't do lock_mount_hash() here, +* ->mnt_ns can change under us. However, if it's +* non-NULL, then there's a reference that won't +* be dropped until after an RCU delay done after +* turning ->mnt_ns NULL. So if we observe it +* non-NULL under rcu_read_lock(), the reference +* we are dropping is not the final one. +*/ +mnt_add_count (mnt,-1 );rcu_read_unlock ();return ; }lock_mount_hash (); +mnt_add_count (mnt,-1 );if (mnt_get_count (mnt)) {rcu_read_unlock ();unlock_mount_hash ();
PATCH 316/366 fix __legitimize_mnt()/mntput() race
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro <[email protected]>
commit 119e1ef80ecfe0d1deb6378d4ab41f5b71519de1 upstream.
__legitimize_mnt() has two problems - one is that in case of success the check of mount_lock is not ordered wrt preceding increment of refcount, making it possible to have successful __legitimize_mnt() on one CPU just before the otherwise final mntpu() on another, with __legitimize_mnt() not seeing mntput() taking the lock and mntput() not seeing the increment done by __legitimize_mnt(). Solved by a pair of barriers.
Another is that failure of __legitimize_mnt() on the second read_seqretry() leaves us with reference that'll need to be dropped by caller; however, if that races with final mntput() we can end up with caller dropping rcu_read_lock() and doing mntput() to release that reference - with the first mntput() having freed the damn thing just as rcu_read_lock() had been dropped. Solution: in "do mntput() yourself" failure case grab mount_lock, check if MNT_DOOMED has been set by racing final mntput() that has missed our increment and if it has - undo the increment and treat that as "failure, caller doesn't need to drop anything" case.
It's not easy to hit - the final mntput() has to come right after the first read_seqretry() in __legitimize_mnt() *and* manage to miss the increment done by __legitimize_mnt() before the second read_seqretry() in there. The things that are almost impossible to hit on bare hardware are not impossible on SMP KVM, though...
[bwh: Backported to 3.16: __legitimize_mnt() has not been split out
from legitimize_mnt(). Adjust the added return statement and comments accordingly.]
--- fs/namespace.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
fs/namespace.c +13 -0
@@ -592,12 +592,20 @@ bool legitimize_mnt(struct vfsmount *basreturn true; mnt =real_mount (bastard);mnt_add_count (mnt,1 ); +smp_mb ();// see mntput_no_expire() if (likely (!read_seqretry (&mount_lock, seq)))return true;if (bastard->mnt_flags &MNT_SYNC_UMOUNT ) {mnt_add_count (mnt,-1 );return false; } +lock_mount_hash (); +if (unlikely (bastard->mnt_flags &MNT_DOOMED )) { +mnt_add_count (mnt,-1 ); +unlock_mount_hash (); +return false; + } +unlock_mount_hash ();rcu_read_unlock ();mntput (bastard);rcu_read_lock ();
@@ -984,6 +992,11 @@ put_again:return ; }lock_mount_hash (); +/* +* make sure that if legitimize_mnt() has not seen us grab +* mount_lock, we'll see their refcount increment here. +*/ +smp_mb ();mnt_add_count (mnt,-1 );if (mnt_get_count (mnt)) {rcu_read_unlock ();
PATCH 317/366 VFS: Impose ordering on accesses of d_inode and d_flags
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: David Howells <[email protected]>
commit 4bf46a272647d89e780126b52eda04737defd9f4 upstream.
Impose ordering on accesses of d_inode and d_flags to avoid the need to do this:
if (!dentry->d_inode || d_is_negative(dentry)) {when this:
if (d_is_negative(dentry)) {should suffice.
This check is especially problematic if a dentry can have its type field set to something other than DENTRY_MISS_TYPE when d_inode is NULL (as in unionmount).
What we really need to do is stick a write barrier between setting d_inode and setting d_flags and a read barrier between reading d_flags and reading d_inode.
[bwh: Backported to 3.16:
- Use ACCESS_ONCE() instead of {READ,WRITE}_ONCE()
- There's no DCACHE_FALLTHRU flag]
--- fs/dcache.c | 47 +++++++++++++++++++++++++++++++++++------- include/linux/dcache.h | 21 +++---------------- 2 files changed, 42 insertions(+), 26 deletions(-)
fs/dcache.c +39 -7
@@ -281,6 +281,41 @@ void release_dentry_name_snapshot(struct }EXPORT_SYMBOL (release_dentry_name_snapshot); +/* +* Make sure other CPUs see the inode attached before the type is set. +*/ +static inline void __d_set_inode_and_type (struct dentry *dentry, +struct inode *inode, +unsigned type_flags) +{ +unsigned flags; + + dentry->d_inode = inode; +smp_wmb (); + flags =ACCESS_ONCE (dentry->d_flags); + flags &= ~DCACHE_ENTRY_TYPE ; + flags |= type_flags; +ACCESS_ONCE (dentry->d_flags) = flags; +} + +/* +* Ideally, we want to make sure that other CPUs see the flags cleared before +* the inode is detached, but this is really a violation of RCU principles +* since the ordering suggests we should always set inode before flags. +* +* We should instead replace or discard the entire dentry - but that sucks +* performancewise on mass deletion/rename. +*/ +static inline void __d_clear_type_and_inode (struct dentry *dentry) +{ +unsigned flags =ACCESS_ONCE (dentry->d_flags); + + flags &= ~DCACHE_ENTRY_TYPE ; +ACCESS_ONCE (dentry->d_flags) = flags; +smp_wmb (); + dentry->d_inode =NULL ; +} +static void dentry_free (struct dentry *dentry) {WARN_ON (!hlist_unhashed (&dentry->d_u.d_alias));
@@ -317,7 +352,7 @@ static void dentry_iput(struct dentry * {struct inode *inode = dentry->d_inode;if (inode) { - dentry->d_inode =NULL ; +__d_clear_type_and_inode (dentry);hlist_del_init (&dentry->d_u.d_alias);spin_unlock (&dentry->d_lock);spin_unlock (&inode->i_lock);
@@ -341,8 +376,7 @@ static void dentry_unlink_inode(struct d __releases(dentry->d_inode->i_lock) {struct inode *inode = dentry->d_inode; -__d_clear_type (dentry); - dentry->d_inode =NULL ; +__d_clear_type_and_inode (dentry);hlist_del_init (&dentry->d_u.d_alias);dentry_rcuwalk_barrier (dentry);spin_unlock (&dentry->d_lock);
@@ -1644,10 +1678,9 @@ static void __d_instantiate(struct dentrunsigned add_flags =d_flags_for_inode (inode);spin_lock (&dentry->d_lock); -__d_set_type (dentry, add_flags);if (inode)hlist_add_head (&dentry->d_u.d_alias, &inode->i_dentry); - dentry->d_inode = inode; +__d_set_inode_and_type (dentry, inode, add_flags);dentry_rcuwalk_barrier (dentry);spin_unlock (&dentry->d_lock);fsnotify_d_instantiate (dentry, inode);
@@ -1904,8 +1937,7 @@ struct dentry *d_obtain_alias(struct ino add_flags =d_flags_for_inode (inode) |DCACHE_DISCONNECTED ;spin_lock (&tmp->d_lock); - tmp->d_inode = inode; - tmp->d_flags |= add_flags; +__d_set_inode_and_type (tmp, inode, add_flags);hlist_add_head (&tmp->d_u.d_alias, &inode->i_dentry);hlist_bl_lock (&tmp->d_sb->s_anon);hlist_bl_add_head (&tmp->d_hash, &tmp->d_sb->s_anon);
include/linux/dcache.h +3 -18
@@ -411,26 +411,11 @@ static inline bool d_mountpoint(const st/* * Directory cache entry type accessor functions. */ -static inline void __d_set_type (struct dentry *dentry,unsigned type) -{ - dentry->d_flags = (dentry->d_flags & ~DCACHE_ENTRY_TYPE ) | type; -} - -static inline void __d_clear_type (struct dentry *dentry) -{ -__d_set_type (dentry,DCACHE_MISS_TYPE ); -} - -static inline void d_set_type (struct dentry *dentry,unsigned type) -{ -spin_lock (&dentry->d_lock); -__d_set_type (dentry, type); -spin_unlock (&dentry->d_lock); -} -static inline unsigned __d_entry_type (const struct dentry *dentry) { -return dentry->d_flags &DCACHE_ENTRY_TYPE ; +unsigned type =ACCESS_ONCE (dentry->d_flags); +smp_rmb (); +return type &DCACHE_ENTRY_TYPE ; }static inline bool d_can_lookup (const struct dentry *dentry)
PATCH 318/366 use ->d_seq to get coherency between ->d_inode and ->d_flags
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro <[email protected]>
commit a528aca7f359f4b0b1d72ae406097e491a5ba9ea upstream.
Games with ordering and barriers are way too brittle. Just bump ->d_seq before and after updating ->d_inode and ->d_flags type bits, so that verifying ->d_seq would guarantee they are coherent.
--- fs/dcache.c | 20 +++++--------------- include/linux/dcache.h | 4 +--- 2 files changed, 6 insertions(+), 18 deletions(-)
fs/dcache.c +5 -12
@@ -291,28 +291,18 @@ static inline void __d_set_inode_and_typunsigned flags; dentry->d_inode = inode; -smp_wmb (); flags =ACCESS_ONCE (dentry->d_flags); flags &= ~DCACHE_ENTRY_TYPE ; flags |= type_flags;ACCESS_ONCE (dentry->d_flags) = flags; } -/* -* Ideally, we want to make sure that other CPUs see the flags cleared before -* the inode is detached, but this is really a violation of RCU principles -* since the ordering suggests we should always set inode before flags. -* -* We should instead replace or discard the entire dentry - but that sucks -* performancewise on mass deletion/rename. -*/ static inline void __d_clear_type_and_inode (struct dentry *dentry) {unsigned flags =ACCESS_ONCE (dentry->d_flags); flags &= ~DCACHE_ENTRY_TYPE ;ACCESS_ONCE (dentry->d_flags) = flags; -smp_wmb (); dentry->d_inode =NULL ; }
@@ -376,9 +366,11 @@ static void dentry_unlink_inode(struct d __releases(dentry->d_inode->i_lock) {struct inode *inode = dentry->d_inode; + +raw_write_seqcount_begin (&dentry->d_seq);__d_clear_type_and_inode (dentry);hlist_del_init (&dentry->d_u.d_alias); -dentry_rcuwalk_barrier (dentry); +raw_write_seqcount_end (&dentry->d_seq);spin_unlock (&dentry->d_lock);spin_unlock (&inode->i_lock);if (!inode->i_nlink)
@@ -1680,8 +1672,9 @@ static void __d_instantiate(struct dentrspin_lock (&dentry->d_lock);if (inode)hlist_add_head (&dentry->d_u.d_alias, &inode->i_dentry); +raw_write_seqcount_begin (&dentry->d_seq);__d_set_inode_and_type (dentry, inode, add_flags); -dentry_rcuwalk_barrier (dentry); +raw_write_seqcount_end (&dentry->d_seq);spin_unlock (&dentry->d_lock);fsnotify_d_instantiate (dentry, inode); }
include/linux/dcache.h +1 -3
@@ -413,9 +413,7 @@ static inline bool d_mountpoint(const st*/ static inline unsigned __d_entry_type (const struct dentry *dentry) { -unsigned type =ACCESS_ONCE (dentry->d_flags); -smp_rmb (); -return type &DCACHE_ENTRY_TYPE ; +return dentry->d_flags &DCACHE_ENTRY_TYPE ; }static inline bool d_can_lookup (const struct dentry *dentry)
PATCH 319/366 unify dentry_iput() and dentry_unlink_inode()
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro <[email protected]>
commit 550dce01dd606c88a837138aa448ccd367fb0cbb upstream.
There is a lot of duplication between dentry_unlink_inode() and dentry_iput(). The only real difference is that dentry_unlink_inode() bumps ->d_seq and dentry_iput() doesn't. The argument of the latter is known to have been unhashed, so anybody who might've found it in RCU lookup would already be doomed to a ->d_seq mismatch. And we want to avoid pointless smp_rmb() there.
This patch makes dentry_unlink_inode() bump ->d_seq only for hashed dentries. It's safe (d_delete() calls that sucker only if we are holding the only reference to dentry, so rehash is not going to happen) and it allows to use dentry_unlink_inode() in __dentry_kill() and get rid of dentry_iput().
The interesting question here is profiling; it *is* a hot path, and extra conditional jumps in there might or might not be painful.
--- fs/dcache.c | 45 ++++++++++----------------------------------- 1 file changed, 10 insertions(+), 35 deletions(-)
fs/dcache.c +10 -35
@@ -333,44 +333,21 @@ static inline void dentry_rcuwalk_barrie/* * Release the dentry's inode, using the filesystem -* d_iput() operation if defined. Dentry has no refcount -* and is unhashed. -*/ -static void dentry_iput (struct dentry * dentry) - __releases(dentry->d_lock) - __releases(dentry->d_inode->i_lock) -{ -struct inode *inode = dentry->d_inode; -if (inode) { -__d_clear_type_and_inode (dentry); -hlist_del_init (&dentry->d_u.d_alias); -spin_unlock (&dentry->d_lock); -spin_unlock (&inode->i_lock); -if (!inode->i_nlink) -fsnotify_inoderemove (inode); -if (dentry->d_op && dentry->d_op->d_iput) - dentry->d_op->d_iput (dentry, inode); -else -iput (inode); - }else { -spin_unlock (&dentry->d_lock); - } -} - -/* -* Release the dentry's inode, using the filesystem -* d_iput() operation if defined. dentry remains in-use. +* d_iput() operation if defined. */ static void dentry_unlink_inode (struct dentry * dentry) __releases(dentry->d_lock) __releases(dentry->d_inode->i_lock) {struct inode *inode = dentry->d_inode; +bool hashed = !d_unhashed (dentry); -raw_write_seqcount_begin (&dentry->d_seq); +if (hashed) +raw_write_seqcount_begin (&dentry->d_seq);__d_clear_type_and_inode (dentry);hlist_del_init (&dentry->d_u.d_alias); -raw_write_seqcount_end (&dentry->d_seq); +if (hashed) +raw_write_seqcount_end (&dentry->d_seq);spin_unlock (&dentry->d_lock);spin_unlock (&inode->i_lock);if (!inode->i_nlink)
@@ -537,12 +514,10 @@ static void __dentry_kill(struct dentry dentry->d_flags |=DCACHE_DENTRY_KILLED ;if (parent)spin_unlock (&parent->d_lock); -dentry_iput (dentry); -/* -* dentry_iput drops the locks, at which point nobody (except -* transient RCU lookups) can reach this dentry. -*/ -BUG_ON ((int )dentry->d_lockref.count >0 ); +if (dentry->d_inode) +dentry_unlink_inode (dentry); +else +spin_unlock (&dentry->d_lock);this_cpu_dec (nr_dentry);if (dentry->d_op && dentry->d_op->d_release) dentry->d_op->d_release (dentry);
PATCH 320/366 make sure that __dentry_kill() always invalidates d_seq, unhashed or not
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro <[email protected]>
commit 4c0d7cd5c8416b1ef41534d19163cb07ffaa03ab upstream.
RCU pathwalk relies upon the assumption that anything that changes ->d_inode of a dentry will invalidate its ->d_seq. That's almost true - the one exception is that the final dput() of already unhashed dentry does *not* touch ->d_seq at all. Unhashing does, though, so for anything we'd found by RCU dcache lookup we are fine. Unfortunately, we can *start* with an unhashed dentry or jump into it.
We could try and be careful in the (few) places where that could happen. Or we could just make the final dput() invalidate the damn thing, unhashed or not. The latter is much simpler and easier to backport, so let's do it that way.
--- fs/dcache.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
fs/dcache.c +2 -5
@@ -340,14 +340,11 @@ static void dentry_unlink_inode(struct d __releases(dentry->d_inode->i_lock) {struct inode *inode = dentry->d_inode; -bool hashed = !d_unhashed (dentry); -if (hashed) -raw_write_seqcount_begin (&dentry->d_seq); +raw_write_seqcount_begin (&dentry->d_seq);__d_clear_type_and_inode (dentry);hlist_del_init (&dentry->d_u.d_alias); -if (hashed) -raw_write_seqcount_end (&dentry->d_seq); +raw_write_seqcount_end (&dentry->d_seq);spin_unlock (&dentry->d_lock);spin_unlock (&inode->i_lock);if (!inode->i_nlink)
PATCH 321/366 xen/netfront: don't cache skb_shinfo()
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Juergen Gross <[email protected]>
commit d472b3a6cf63cd31cae1ed61930f07e6cd6671b5 upstream.
skb_shinfo() can change when calling __pskb_pull_tail(): Don't cache its return value.
--- drivers/net/xen-netfront.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/net/xen-netfront.c +4 -4
@@ -898,7 +898,6 @@ static RING_IDX xennet_fill_frags(structstruct sk_buff *skb, struct sk_buff_head *list) { - struct skb_shared_info *shinfo = skb_shinfo(skb); RING_IDX cons = queue->rx.rsp_cons;struct sk_buff *nskb;
@@ -907,15 +906,16 @@ static RING_IDX xennet_fill_frags(structRING_GET_RESPONSE (&queue->rx, ++cons);skb_frag_t *nfrag = &skb_shinfo (nskb)->frags[0 ]; -if (shinfo->nr_frags ==MAX_SKB_FRAGS ) { +if (skb_shinfo (skb)->nr_frags ==MAX_SKB_FRAGS ) {unsigned int pull_to =NETFRONT_SKB_CB (skb)->pull_to;BUG_ON (pull_to <=skb_headlen (skb));__pskb_pull_tail (skb, pull_to -skb_headlen (skb)); } -BUG_ON (shinfo->nr_frags >=MAX_SKB_FRAGS ); +BUG_ON (skb_shinfo (skb)->nr_frags >=MAX_SKB_FRAGS ); -skb_add_rx_frag (skb, shinfo->nr_frags,skb_frag_page (nfrag), +skb_add_rx_frag (skb,skb_shinfo (skb)->nr_frags, +skb_frag_page (nfrag), rx->offset, rx->status,PAGE_SIZE );skb_shinfo (nskb)->nr_frags =0 ;
PATCH 322/366 ALSA: msnd: add some missing curly braces
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
commit 096a020a9ef5c947577d3b57199bfc9b7e686b49 upstream.
There were some curly braces intended here.
--- sound/isa/msnd/msnd_pinnacle_mixer.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
sound/isa/msnd/msnd_pinnacle_mixer.c +2 -1
@@ -313,11 +313,12 @@ int snd_msndmix_new(struct snd_card *carspin_lock_init (&chip->mixer_lock);strcpy (card->mixername,"MSND Pinnacle Mixer" ); -for (idx =0 ; idx <ARRAY_SIZE (snd_msnd_controls); idx++) +for (idx =0 ; idx <ARRAY_SIZE (snd_msnd_controls); idx++) { err =snd_ctl_add (card,snd_ctl_new1 (snd_msnd_controls + idx, chip));if (err <0 )return err; + }return 0 ; }
PATCH 323/366 media: v4l: event: Prevent freeing event subscriptions while accessed
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Sakari Ailus <[email protected]>
commit ad608fbcf166fec809e402d548761768f602702c upstream.
The event subscriptions are added to the subscribed event list while holding a spinlock, but that lock is subsequently released while still accessing the subscription object. This makes it possible to unsubscribe the event --- and freeing the subscription object's memory --- while the subscription object is simultaneously accessed.
Prevent this by adding a mutex to serialise the event subscription and unsubscription. This also gives a guarantee to the callback ops that the add op has returned before the del op is called.
This change also results in making the elems field less special:
subscriptions are only added to the event list once they are fully initialised.
--- drivers/media/v4l2-core/v4l2-event.c | 38 +++++++++++++++++++----------------- drivers/media/v4l2-core/v4l2-fh.c | 2 ++ include/media/v4l2-fh.h | 1 + 3 files changed, 23 insertions(+), 18 deletions(-)
drivers/media/v4l2-core/v4l2-event.c +20 -18
@@ -119,14 +119,6 @@ static void __v4l2_event_queue_fh(structif (sev ==NULL )return ; -/* -* If the event has been added to the fh->subscribed list, but its -* add op has not completed yet elems will be 0, treat this as -* not being subscribed. -*/ -if (!sev->elems) -return ; -/* Increase event sequence number on fh. */ fh->sequence++;
@@ -209,6 +201,7 @@ int v4l2_event_subscribe(struct v4l2_fhstruct v4l2_subscribed_event *sev, *found_ev;unsigned long flags;unsigned i; +int ret =0 ;if (sub->type ==V4L2_EVENT_ALL )return -EINVAL ;
@@ -226,31 +219,36 @@ int v4l2_event_subscribe(struct v4l2_fh sev->flags = sub->flags; sev->fh = fh; sev->ops = ops; + sev->elems = elems; + +mutex_lock (&fh->subscribe_lock);spin_lock_irqsave (&fh->vdev->fh_lock, flags); found_ev =v4l2_event_subscribed (fh, sub->type, sub->id); -if (!found_ev) -list_add (&sev->list, &fh->subscribed);spin_unlock_irqrestore (&fh->vdev->fh_lock, flags);if (found_ev) { +/* Already listening */ kfree (sev); -return 0 ;/* Already listening */ + goto out_unlock; }if (sev->ops && sev->ops->add) { -int ret = sev->ops->add (sev, elems); + ret = sev->ops->add (sev, elems);if (ret) { - sev->ops =NULL ; -v4l2_event_unsubscribe (fh, sub); -return ret; +kfree (sev); + goto out_unlock; } } -/* Mark as ready for use */ - sev->elems = elems; +spin_lock_irqsave (&fh->vdev->fh_lock, flags); +list_add (&sev->list, &fh->subscribed); +spin_unlock_irqrestore (&fh->vdev->fh_lock, flags); + +out_unlock: +mutex_unlock (&fh->subscribe_lock); -return 0 ; +return ret; }EXPORT_SYMBOL_GPL (v4l2_event_subscribe);
@@ -289,6 +287,8 @@ int v4l2_event_unsubscribe(struct v4l2_freturn 0 ; } +mutex_lock (&fh->subscribe_lock); +spin_lock_irqsave (&fh->vdev->fh_lock, flags); sev =v4l2_event_subscribed (fh, sub->type, sub->id);
@@ -306,6 +306,8 @@ int v4l2_event_unsubscribe(struct v4l2_fif (sev && sev->ops && sev->ops->del) sev->ops->del (sev); +mutex_unlock (&fh->subscribe_lock); +kfree (sev);return 0 ;
drivers/media/v4l2-core/v4l2-fh.c +2 -0
@@ -42,6 +42,7 @@ void v4l2_fh_init(struct v4l2_fh *fh, stINIT_LIST_HEAD (&fh->available);INIT_LIST_HEAD (&fh->subscribed); fh->sequence =-1 ; +mutex_init (&fh->subscribe_lock); }EXPORT_SYMBOL_GPL (v4l2_fh_init);
@@ -88,6 +89,7 @@ void v4l2_fh_exit(struct v4l2_fh *fh)if (fh->vdev ==NULL )return ;v4l2_event_unsubscribe_all (fh); +mutex_destroy (&fh->subscribe_lock); fh->vdev =NULL ; }EXPORT_SYMBOL_GPL (v4l2_fh_exit);
include/media/v4l2-fh.h +1 -0
@@ -41,6 +41,7 @@ struct v4l2_fh {/* Events */ wait_queue_head_t wait; +struct mutex subscribe_lock;struct list_head subscribed;/* Subscribed events */ struct list_head available;/* Dequeueable event */ unsigned int navailable;
PATCH 324/366 ceph: fix llistxattr on symlink
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: "Yan, Zheng" <[email protected]>
commit 0abb43dcacb52145aa265f82c914375d59dfe2da upstream.
only regular file and directory have vxattrs.
--- fs/ceph/xattr.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
fs/ceph/xattr.c +1 -2
@@ -284,8 +284,7 @@ static size_t ceph_vxattrs_name_size(strreturn ceph_dir_vxattrs_name_size;if (vxattrs == ceph_file_vxattrs)return ceph_file_vxattrs_name_size; -BUG (); - +BUG_ON (vxattrs);return 0 ; }
PATCH 325/366 ceph: use lookup request to revalidate dentry
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: "Yan, Zheng" <[email protected]>
commit 200fd27c8fa2ba8bb4529033967b69a7cbfa2c2e upstream.
If dentry has no lease, ceph_d_revalidate() previously return 0. This causes VFS to invalidate the dentry and create a new dentry for later lookup. Invalidating a dentry also detach any underneath mount points. So mount point inside cephfs can disapear mystically (even the mount point is not modified by other hosts).
The fix is using lookup request to revalidate dentry without lease. This can partly solve the mount points disapear issue (as long as the mount point is not modified by other hosts)
--- fs/ceph/dir.c | 34 ++++++++++++++++++++++++++++++++++ fs/ceph/inode.c | 1 + 2 files changed, 35 insertions(+)
fs/ceph/dir.c +34 -0
@@ -1064,6 +1064,40 @@ static int ceph_d_revalidate(struct dent valid =1 ; } +if (!valid) { +struct ceph_mds_client *mdsc = +ceph_sb_to_client (dir->i_sb)->mdsc; +struct ceph_mds_request *req; +int op, mask, err; + + op =ceph_snap (dir) ==CEPH_SNAPDIR ? +CEPH_MDS_OP_LOOKUPSNAP :CEPH_MDS_OP_LOOKUP ; + req =ceph_mdsc_create_request (mdsc, op,USE_ANY_MDS ); +if (!IS_ERR (req)) { + req->r_dentry =dget (dentry); + req->r_num_caps =2 ; + + mask =CEPH_STAT_CAP_INODE |CEPH_CAP_AUTH_SHARED ; +if (ceph_security_xattr_wanted (dir)) + mask |=CEPH_CAP_XATTR_SHARED ; + req->r_args.getattr.mask = mask; + + req->r_locked_dir = dir; + err =ceph_mdsc_do_request (mdsc,NULL , req); +if (err ==0 || err == -ENOENT ) { +if (dentry == req->r_dentry) { + valid = !d_unhashed (dentry); + }else { +d_invalidate (req->r_dentry); + err = -EAGAIN ; + } + } +ceph_mdsc_put_request (req); +dout ("d_revalidate %p lookup result=%d\n" , + dentry, err); + } + } +dout ("d_revalidate %p %s\n" , dentry, valid ?"valid" :"invalid" );if (valid) {ceph_dentry_lru_touch (dentry);
fs/ceph/inode.c +1 -0
@@ -1251,6 +1251,7 @@ retry_lookup:dout (" %p links to %p %llx.%llx, not %llx.%llx\n" , dn, dn->d_inode,ceph_vinop (dn->d_inode),ceph_vinop (in)); +d_invalidate (dn); have_lease = false; }
fs/ceph/super.h +9 -0
@@ -736,6 +736,15 @@ extern void __ceph_destroy_xattrs(structextern void __init ceph_xattr_init (void );extern void ceph_xattr_exit (void ); +#ifdef CONFIG_SECURITY +extern bool ceph_security_xattr_wanted (struct inode *in); +#else +static inline bool ceph_security_xattr_wanted (struct inode *in) +{ +return false; +} +#endif +/* acl.c */ extern const struct xattr_handler *ceph_xattr_handlers[];
fs/ceph/xattr.c +7 -0
@@ -1128,3 +1128,10 @@ int ceph_removexattr(struct dentry *dentreturn __ceph_removexattr (dentry, name); } + +#ifdef CONFIG_SECURITY +bool ceph_security_xattr_wanted (struct inode *in) +{ +return in->i_security !=NULL ; +} +#endif
PATCH 326/366 ceph: don't set req->r_locked_dir in ceph_d_revalidate
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Jeff Layton <[email protected]>
commit c3f4688a08fd86f1bf8e055724c84b7a40a09733 upstream.
This function sets req->r_locked_dir which is supposed to indicate to ceph_fill_trace that the parent's i_rwsem is locked for write. Unfortunately, there is no guarantee that the dir will be locked when d_revalidate is called, so we really don't want ceph_fill_trace to do any dcache manipulation from this context. Clear req->r_locked_dir since it's clearly not safe to do that.
What we really want to know with d_revalidate is whether the dentry still points to the same inode. ceph_fill_trace installs a pointer to the inode in req->r_target_inode, so we can just compare that to d_inode(dentry) to see if it's the same one after the lookup.
Also, since we aren't generally interested in the parent here, we can switch to using a GETATTR to hint that to the MDS, which also means that we only need to reserve one cap.
Finally, just remove the d_unhashed check. That's really outside the purview of a filesystem's d_revalidate. If the thing became unhashed while we're checking it, then that's up to the VFS to handle anyway.
[bwh: Backported to 3.16: s/d_really_is_(positive|negative)/d_is_\1/ since
we don't have to consider overlayfs]
--- fs/ceph/dir.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-)
fs/ceph/dir.c +14 -10
@@ -1071,26 +1071,30 @@ static int ceph_d_revalidate(struct dentint op, mask, err; op =ceph_snap (dir) ==CEPH_SNAPDIR ? -CEPH_MDS_OP_LOOKUPSNAP :CEPH_MDS_OP_LOOKUP ; +CEPH_MDS_OP_LOOKUPSNAP :CEPH_MDS_OP_GETATTR ; req =ceph_mdsc_create_request (mdsc, op,USE_ANY_MDS );if (!IS_ERR (req)) { req->r_dentry =dget (dentry); - req->r_num_caps =2 ; + req->r_num_caps = op ==CEPH_MDS_OP_GETATTR ?1 :2 ; mask =CEPH_STAT_CAP_INODE |CEPH_CAP_AUTH_SHARED ;if (ceph_security_xattr_wanted (dir)) mask |=CEPH_CAP_XATTR_SHARED ; req->r_args.getattr.mask = mask; - req->r_locked_dir = dir; err =ceph_mdsc_do_request (mdsc,NULL , req); -if (err ==0 || err == -ENOENT ) { -if (dentry == req->r_dentry) { - valid = !d_unhashed (dentry); - }else { -d_invalidate (req->r_dentry); - err = -EAGAIN ; - } +switch (err) { +case 0 : +if (d_is_positive (dentry) && +d_inode (dentry) == req->r_target_inode) + valid =1 ; +break ; +case -ENOENT : +if (d_is_negative (dentry)) + valid =1 ; +/* Fallthrough */ +default : +break ; }ceph_mdsc_put_request (req); dout("d_revalidate %p lookup result=%d\n",
PATCH 327/366 ceph: fix endianness of getattr mask in ceph_d_revalidate
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Jeff Layton <[email protected]>
commit 1097680d759918ce4a8705381c0ab2ed7bd60cf1 upstream.
sparse says:
fs/ceph/dir.c:1248:50: warning: incorrect type in assignment (different base types)
fs/ceph/dir.c:1248:50: expected restricted __le32 [usertype] mask
fs/ceph/dir.c:1248:50: got int [signed] [assigned] mask--- fs/ceph/dir.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
fs/ceph/dir.c +3 -2
@@ -1068,7 +1068,8 @@ static int ceph_d_revalidate(struct dentstruct ceph_mds_client *mdsc =ceph_sb_to_client (dir->i_sb)->mdsc;struct ceph_mds_request *req; -int op, mask, err; +int op, err; +u32 mask; op =ceph_snap (dir) ==CEPH_SNAPDIR ?CEPH_MDS_OP_LOOKUPSNAP :CEPH_MDS_OP_GETATTR ;
@@ -1080,7 +1081,7 @@ static int ceph_d_revalidate(struct dent mask =CEPH_STAT_CAP_INODE |CEPH_CAP_AUTH_SHARED ;if (ceph_security_xattr_wanted (dir)) mask |=CEPH_CAP_XATTR_SHARED ; - req->r_args.getattr.mask = mask; + req->r_args.getattr.mask =cpu_to_le32 (mask); err =ceph_mdsc_do_request (mdsc,NULL , req);switch (err) {
PATCH 328/366 dm bufio: avoid sleeping while holding the dm_bufio lock
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Douglas Anderson <[email protected]>
commit 9ea61cac0b1ad0c09022f39fd97e9b99a2cfc2dc upstream.
We've seen in-field reports showing _lots_ (18 in one case, 41 in another) of tasks all sitting there blocked on:
mutex_lock+0x4c/0x68 dm_bufio_shrink_count+0x38/0x78 shrink_slab.part.54.constprop.65+0x100/0x464 shrink_zone+0xa8/0x198
In the two cases analyzed, we see one task that looks like this:
Workqueue: kverityd verity_prefetch_io __switch_to+0x9c/0xa8 __schedule+0x440/0x6d8 schedule+0x94/0xb4 schedule_timeout+0x204/0x27c schedule_timeout_uninterruptible+0x44/0x50 wait_iff_congested+0x9c/0x1f0 shrink_inactive_list+0x3a0/0x4cc shrink_lruvec+0x418/0x5cc shrink_zone+0x88/0x198 try_to_free_pages+0x51c/0x588 __alloc_pages_nodemask+0x648/0xa88 __get_free_pages+0x34/0x7c alloc_buffer+0xa4/0x144 __bufio_new+0x84/0x278 dm_bufio_prefetch+0x9c/0x154 verity_prefetch_io+0xe8/0x10c process_one_work+0x240/0x424 worker_thread+0x2fc/0x424 kthread+0x10c/0x114
...and that looks to be the one holding the mutex.
The problem has been reproduced on fairly easily:
0. Be running Chrome OS w/ verity enabled on the root filesystem
1. Pick test patch: http://crosreview.com/412360
2. Install launchBalloons.sh and balloon.arm from
http://crbug.com/468342 ...that's just a memory stress test app. 3. On a 4GB rk3399 machine, run nice ./launchBalloons.sh 4 900 100000
...that tries to eat 4 * 900 MB of memory and keep accessing.
4. Login to the Chrome web browser and restore many tabs
With that, I've seen printouts like:
DOUG: long bufio 90758 ms
...and stack trace always show's we're in dm_bufio_prefetch().
The problem is that we try to allocate memory with GFP_NOIO while we're holding the dm_bufio lock. Instead we should be using GFP_NOWAIT. Using GFP_NOIO can cause us to sleep while holding the lock and that causes the above problems.
The current behavior explained by David Rientjes:
It will still try reclaim initially because __GFP_WAIT (or __GFP_KSWAPD_RECLAIM) is set by GFP_NOIO. This is the cause of contention on dm_bufio_lock() that the thread holds. You want to pass GFP_NOWAIT instead of GFP_NOIO to alloc_buffer() when holding a mutex that can be contended by a concurrent slab shrinker (if count_objects didn't use a trylock, this pattern would trivially deadlock).
This change significantly increases responsiveness of the system while in this state. It makes a real difference because it unblocks kswapd. In the bug report analyzed, kswapd was hung:
kswapd0 D ffffffc000204fd8 0 72 2 0x00000000
Call trace: [<ffffffc000204fd8>] __switch_to+0x9c/0xa8 [<ffffffc00090b794>] __schedule+0x440/0x6d8 [<ffffffc00090bac0>] schedule+0x94/0xb4 [<ffffffc00090be44>] schedule_preempt_disabled+0x28/0x44 [<ffffffc00090d900>] __mutex_lock_slowpath+0x120/0x1ac [<ffffffc00090d9d8>] mutex_lock+0x4c/0x68 [<ffffffc000708e7c>] dm_bufio_shrink_count+0x38/0x78 [<ffffffc00030b268>] shrink_slab.part.54.constprop.65+0x100/0x464 [<ffffffc00030dbd8>] shrink_zone+0xa8/0x198 [<ffffffc00030e578>] balance_pgdat+0x328/0x508 [<ffffffc00030eb7c>] kswapd+0x424/0x51c [<ffffffc00023f06c>] kthread+0x10c/0x114 [<ffffffc000203dd0>] ret_from_fork+0x10/0x40
By unblocking kswapd memory pressure should be reduced.
--- drivers/md/dm-bufio.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/md/dm-bufio.c +3 -2
@@ -778,7 +778,8 @@ static struct dm_buffer *__alloc_buffer_* dm-bufio is resistant to allocation failures (it just keeps * one buffer reserved in cases all the allocations fail). * So set flags to not try too hard: -* GFP_NOIO: don't recurse into the I/O layer +* GFP_NOWAIT: don't wait; if we need to sleep we'll release our +* mutex and wait ourselves. * __GFP_NORETRY: don't retry and rather return failure * __GFP_NOMEMALLOC: don't use emergency reserves * __GFP_NOWARN: don't print a warning in case of failure
@@ -788,7 +789,7 @@ static struct dm_buffer *__alloc_buffer_*/ while (1 ) {if (dm_bufio_cache_size_latch !=1 ) { - b =alloc_buffer (c,GFP_NOIO | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN); + b =alloc_buffer (c,GFP_NOWAIT | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN);if (b)return b; }
PATCH 329/366 dm bufio: drop the lock when doing GFP_NOIO allocation
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Mikulas Patocka <[email protected]>
commit 41c73a49df31151f4ff868f28fe4f129f113fa2c upstream.
If the first allocation attempt using GFP_NOWAIT fails, drop the lock and retry using GFP_NOIO allocation (lock is dropped because the allocation can take some time).
Note that we won't do GFP_NOIO allocation when we loop for the second time, because the lock shouldn't be dropped between __wait_for_free_buffer and __get_unclaimed_buffer.
--- drivers/md/dm-bufio.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
drivers/md/dm-bufio.c +10 -0
@@ -773,6 +773,7 @@ enum new_flag {static struct dm_buffer *__alloc_buffer_wait_no_callback (struct dm_bufio_client *c,enum new_flag nf) {struct dm_buffer *b; +bool tried_noio_alloc = false;/* * dm-bufio is resistant to allocation failures (it just keeps
@@ -797,6 +798,15 @@ static struct dm_buffer *__alloc_buffer_if (nf ==NF_PREFETCH )return NULL ; +if (dm_bufio_cache_size_latch !=1 && !tried_noio_alloc) { +dm_bufio_unlock (c); + b =alloc_buffer (c,GFP_NOIO | __GFP_NORETRY | __GFP_NOMEMALLOC | __GFP_NOWARN); +dm_bufio_lock (c); +if (b) +return b; + tried_noio_alloc = true; + } +if (!list_empty (&c->reserved_buffers)) { b =list_entry (c->reserved_buffers.next, struct dm_buffer, lru_list);
PATCH 330/366 fs/proc: Stop trying to report thread stacks
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Andy Lutomirski <[email protected]>
commit b18cb64ead400c01bf1580eeba330ace51f8087d upstream.
This reverts more of:
b76437579d13 ("procfs: mark thread stack correctly in proc/<pid>/maps")
... which was partially reverted by:
65376df58217 ("proc: revert /proc/<pid>/maps [stack:TID] annotation")
Originally, /proc/PID/task/TID/maps was the same as /proc/TID/maps.
In current kernels, /proc/PID/maps (or /proc/TID/maps even for threads) shows "[stack]" for VMAs in the mm's stack address range.
In contrast, /proc/PID/task/TID/maps uses KSTK_ESP to guess the target thread's stack's VMA. This is racy, probably returns garbage and, on arches with CONFIG_TASK_INFO_IN_THREAD=y, is also crash-prone:KSTK_ESP is not safe to use on tasks that aren't known to be running ordinary process-context kernel code.
This patch removes the difference and just shows "[stack]" for VMAs in the mm's stack range. This is IMO much more sensible -- the actual "stack" address really is treated specially by the VM code, and the current thread stack isn't even well-defined for programs that frequently switch stacks on their own.
[bwh: Backported to 3.16: Squash in the earlier commits 58cb65487e92
"proc/maps: make vm_is_stack() logic namespace-friendly" and 65376df58217 "proc: revert /proc/<pid>/maps [stack:TID] annotation", which would introduce build failures if applied separately.]
---
fs/proc/task_mmu.c +20 -32
@@ -250,13 +250,28 @@ static int do_maps_open(struct inode *inreturn ret; } +/* +* Indicate if the VMA is a stack for the given task; for +* /proc/PID/maps that is the stack of the main task. +*/ +static int is_stack (struct proc_maps_private *priv, +struct vm_area_struct *vma) +{ +/* +* We make no effort to guess what a given thread considers to be +* its "stack". It's not even well-defined for programs written +* languages like Go. +*/ +return vma->vm_start <= vma->vm_mm->start_stack && + vma->vm_end >= vma->vm_mm->start_stack; +} +static void show_map_vma (struct seq_file *m,struct vm_area_struct *vma,int is_pid) {struct mm_struct *mm = vma->vm_mm;struct file *file = vma->vm_file;struct proc_maps_private *priv = m->private; -struct task_struct *task = priv->task;vm_flags_t flags = vma->vm_flags;unsigned long ino =0 ;unsigned long long pgoff =0 ;
@@ -304,8 +319,6 @@ show_map_vma(struct seq_file *m, struct name =arch_vma_name (vma);if (!name) { -pid_t tid; -if (!mm) { name ="[vdso]" ; goto done;
@@ -317,22 +330,8 @@ show_map_vma(struct seq_file *m, struct goto done; } - tid =vm_is_stack (task, vma, is_pid); - -if (tid !=0 ) { -/* -* Thread stack in /proc/PID/task/TID/maps or -* the main process stack. -*/ -if (!is_pid || (vma->vm_start <= mm->start_stack && - vma->vm_end >= mm->start_stack)) { - name ="[stack]" ; - }else { -/* Thread stack in /proc/PID/maps */ -seq_pad (m,' ' ); -seq_printf (m,"[stack:%d]" , tid); - } - } +if (is_stack (priv, vma)) + name ="[stack]" ; } done:
@@ -1433,19 +1432,8 @@ static int show_numa_map(struct seq_fileseq_path (m, &file->f_path,"\n\t= " ); }else if (vma->vm_start <= mm->brk && vma->vm_end >= mm->start_brk) {seq_puts (m," heap" ); - }else { -pid_t tid =vm_is_stack (task, vma, is_pid); -if (tid !=0 ) { -/* -* Thread stack in /proc/PID/task/TID/maps or -* the main process stack. -*/ -if (!is_pid || (vma->vm_start <= mm->start_stack && - vma->vm_end >= mm->start_stack)) -seq_puts (m," stack" ); -else -seq_printf (m," stack:%d" , tid); - } + }else if (is_stack (proc_priv, vma)) { +seq_puts (m," stack" ); }if (is_vm_hugetlb_page (vma))
fs/proc/task_nommu.c +17 -15
@@ -123,6 +123,20 @@ unsigned long task_statm(struct mm_strucreturn size; } +static int is_stack (struct proc_maps_private *priv, +struct vm_area_struct *vma) +{ +struct mm_struct *mm = vma->vm_mm; + +/* +* We make no effort to guess what a given thread considers to be +* its "stack". It's not even well-defined for programs written +* languages like Go. +*/ +return vma->vm_start <= mm->start_stack && + vma->vm_end >= mm->start_stack; +} +/* * display a single VMA to a sequenced file */
@@ -162,21 +176,9 @@ static int nommu_vma_show(struct seq_filif (file) {seq_pad (m,' ' );seq_path (m, &file->f_path,"" ); - }else if (mm) { -pid_t tid =vm_is_stack (priv->task, vma, is_pid); - -if (tid !=0 ) { -seq_pad (m,' ' ); -/* -* Thread stack in /proc/PID/task/TID/maps or -* the main process stack. -*/ -if (!is_pid || (vma->vm_start <= mm->start_stack && - vma->vm_end >= mm->start_stack)) -seq_printf (m,"[stack]" ); -else -seq_printf (m,"[stack:%d]" , tid); - } + }else if (mm &&is_stack (priv, vma)) { +seq_pad (m,' ' ); +seq_printf (m,"[stack]" ); }seq_putc (m,'\n' );
include/linux/mm.h +1 -2
@@ -1239,8 +1239,7 @@ int set_page_dirty_lock(struct page *pagint clear_page_dirty_for_io (struct page *page);int get_cmdline (struct task_struct *task,char *buffer,int buflen); -extern pid_t -vm_is_stack (struct task_struct *task,struct vm_area_struct *vma,int in_group); +int vma_is_stack_for_task (struct vm_area_struct *vma,struct task_struct *t); extern unsigned long move_page_tables(struct vm_area_struct *vma, unsigned long old_addr, struct vm_area_struct *new_vma,
mm/util.c +1 -33
@@ -255,43 +255,11 @@ void __vma_link_list(struct mm_struct *m }/* Check if the vma is being used as a stack by this task */ -static int vm_is_stack_for_task (struct task_struct *t, -struct vm_area_struct *vma) +int vma_is_stack_for_task (struct vm_area_struct *vma,struct task_struct *t) {return (vma->vm_start <=KSTK_ESP (t) && vma->vm_end >=KSTK_ESP (t)); } -/* -* Check if the vma is being used as a stack. -* If is_group is non-zero, check in the entire thread group or else -* just check in the current task. Returns the pid of the task that -* the vma is stack for. -*/ -pid_t vm_is_stack (struct task_struct *task, -struct vm_area_struct *vma,int in_group) -{ -pid_t ret =0 ; - -if (vm_is_stack_for_task (task, vma)) -return task->pid; - -if (in_group) { -struct task_struct *t; - -rcu_read_lock (); -for_each_thread (task, t) { -if (vm_is_stack_for_task (t, vma)) { - ret = t->pid; - goto done; - } - } -done: -rcu_read_unlock (); - } - -return ret; -} -#if defined(CONFIG_MMU ) && !defined(HAVE_ARCH_PICK_MMAP_LAYOUT )void arch_pick_mmap_layout (struct mm_struct *mm) {
Documentation/filesystems/proc.txt +1 -30
@@ -335,7 +335,7 @@ address perms offset dev in a7cb1000-a7cb2000 ---p 00000000 00:00 0 a7cb2000-a7eb2000 rw-p 00000000 00:00 0 a7eb2000-a7eb3000 ---p 00000000 00:00 0 -a7eb3000-a7ed5000 rw-p 00000000 00:00 0 [stack:1001] +a7eb3000-a7ed5000 rw-p 00000000 00:00 0 a7ed5000-a8008000 r-xp 00000000 03:00 4222 /lib/libc.so.6 a8008000-a800a000 r--p 00133000 03:00 4222 /lib/libc.so.6 a800a000-a800b000 rw-p 00135000 03:00 4222 /lib/libc.so.6
@@ -367,40 +367,11 @@ is not associated with a file: [heap] = the heap of the program [stack] = the stack of the main process - [stack:1001] = the stack of the thread with tid 1001 [vdso] = the "virtual dynamic shared object", the kernel system call handler or if empty, the mapping is anonymous. -The /proc/PID/task/TID/maps is a view of the virtual memory from the viewpoint -of the individual tasks of a process. In this file you will see a mapping marked -as [stack] if that task sees it as a stack. This is a key difference from the -content of /proc/PID/maps, where you will see all mappings that are being used -as stack by all of those tasks. Hence, for the example above, the task-level -map, i.e. /proc/PID/task/TID/maps for thread 1001 will look like this: - -08048000-08049000 r-xp 00000000 03:00 8312 /opt/test -08049000-0804a000 rw-p 00001000 03:00 8312 /opt/test -0804a000-0806b000 rw-p 00000000 00:00 0 [heap] -a7cb1000-a7cb2000 ---p 00000000 00:00 0 -a7cb2000-a7eb2000 rw-p 00000000 00:00 0 -a7eb2000-a7eb3000 ---p 00000000 00:00 0 -a7eb3000-a7ed5000 rw-p 00000000 00:00 0 [stack] -a7ed5000-a8008000 r-xp 00000000 03:00 4222 /lib/libc.so.6 -a8008000-a800a000 r--p 00133000 03:00 4222 /lib/libc.so.6 -a800a000-a800b000 rw-p 00135000 03:00 4222 /lib/libc.so.6 -a800b000-a800e000 rw-p 00000000 00:00 0 -a800e000-a8022000 r-xp 00000000 03:00 14462 /lib/libpthread.so.0 -a8022000-a8023000 r--p 00013000 03:00 14462 /lib/libpthread.so.0 -a8023000-a8024000 rw-p 00014000 03:00 14462 /lib/libpthread.so.0 -a8024000-a8027000 rw-p 00000000 00:00 0 -a8027000-a8043000 r-xp 00000000 03:00 8317 /lib/ld-linux.so.2 -a8043000-a8044000 r--p 0001b000 03:00 8317 /lib/ld-linux.so.2 -a8044000-a8045000 rw-p 0001c000 03:00 8317 /lib/ld-linux.so.2 -aff35000-aff4a000 rw-p 00000000 00:00 0 -ffffe000-fffff000 r-xp 00000000 00:00 0 [vdso] - The /proc/PID/smaps is an extension based on maps, showing the memory consumption for each of the process's mappings. For each of mappings there is a series of lines such as the following:
PATCH 331/366 leds: do not overflow sysfs buffer in led_trigger_show
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Nathan Sullivan <[email protected]>
commit 3b9b95363c45365d606ad4bbba16acca75fdf6d3 upstream.
Per the documentation, use scnprintf instead of sprintf to ensure there is never more than PAGE_SIZE bytes of trigger names put into the buffer.
--- drivers/leds/led-triggers.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-)
drivers/leds/led-triggers.c +7 -5
@@ -78,21 +78,23 @@ ssize_t led_trigger_show(struct device *down_read (&led_cdev->trigger_lock);if (!led_cdev->trigger) - len +=sprintf (buf+len,"[none] " ); + len +=scnprintf (buf+len,PAGE_SIZE - len,"[none] " );else - len +=sprintf (buf+len,"none " ); + len +=scnprintf (buf+len,PAGE_SIZE - len,"none " );list_for_each_entry (trig, &trigger_list, next_trig) {if (led_cdev->trigger && !strcmp (led_cdev->trigger->name, trig->name)) - len +=sprintf (buf+len,"[%s] " , trig->name); + len +=scnprintf (buf+len,PAGE_SIZE - len,"[%s] " , + trig->name);else - len +=sprintf (buf+len,"%s " , trig->name); + len +=scnprintf (buf+len,PAGE_SIZE - len,"%s " , + trig->name); }up_read (&led_cdev->trigger_lock);up_read (&triggers_list_lock); - len +=sprintf (len+buf,"\n" ); + len +=scnprintf (len+buf,PAGE_SIZE - len,"\n" );return len; }EXPORT_SYMBOL_GPL (led_trigger_show);
PATCH 332/366 HID: usbhid: add quirk for innomedia INNEX GENESIS/ATARI adapter
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Tomasz Kramkowski <[email protected]>
commit 9547837bdccb4af127528b36a73377150658b4ac upstream.
The (1292:4745) Innomedia INNEX GENESIS/ATARI adapter needs HID_QUIRK_MULTI_INPUT to split the device up into two controllers instead of inputs from both being merged into one.
--- drivers/hid/hid-ids.h | 3 +++ drivers/hid/usbhid/hid-quirks.c | 1 + 2 files changed, 4 insertions(+)
drivers/hid/hid-ids.h +3 -0
@@ -530,6 +530,9 @@#define USB_VENDOR_ID_IRTOUCHSYSTEMS 0x6615#define USB_DEVICE_ID_IRTOUCH_INFRARED_USB 0x0070 +#define USB_VENDOR_ID_INNOMEDIA 0x1292 +#define USB_DEVICE_ID_INNEX_GENESIS_ATARI 0x4745 +#define USB_VENDOR_ID_JABRA 0x0b0e#define USB_DEVICE_ID_JABRA_SPEAK_410 0x0412#define USB_DEVICE_ID_JABRA_SPEAK_510 0x0420
drivers/hid/usbhid/hid-quirks.c +1 -0
@@ -175,6 +175,7 @@ static const struct hid_blacklist { { USB_VENDOR_ID_MULTIPLE_1781, USB_DEVICE_ID_RAPHNET_4NES4SNES_OLD, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_DRACAL_RAPHNET, USB_DEVICE_ID_RAPHNET_2NES2SNES, HID_QUIRK_MULTI_INPUT }, { USB_VENDOR_ID_DRACAL_RAPHNET, USB_DEVICE_ID_RAPHNET_4NES4SNES, HID_QUIRK_MULTI_INPUT }, + { USB_VENDOR_ID_INNOMEDIA, USB_DEVICE_ID_INNEX_GENESIS_ATARI, HID_QUIRK_MULTI_INPUT }, { 0, 0 } };
PATCH 333/366 HID: reject input outside logical range only if null state is set
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Valtteri Heikkilä <[email protected]>
commit 3f3752705dbd50b66b66ad7b4d54fe33d2f746ed upstream.
This patch fixes an issue in drivers/hid/hid-input.c where USB HID control null state flag is not checked upon rejecting inputs outside logical minimum-maximum range. The check should be made according to USB HID specification 1.11, section 6.2.2.5, p.31. The fix will resolve issues with some game controllers, such as:
https://bugzilla.kernel.org/show_bug.cgi?id=68621
--- drivers/hid/hid-input.c | 1 + 1 file changed, 1 insertion(+)
drivers/hid/hid-input.c +1 -0
@@ -1094,6 +1094,7 @@ void hidinput_hid_event(struct hid_devic* don't specify logical min and max. */ if ((field->flags &HID_MAIN_ITEM_VARIABLE ) && + (field->flags &HID_MAIN_ITEM_NULL_STATE ) && (field->logical_minimum < field->logical_maximum) && (value < field->logical_minimum || value > field->logical_maximum)) {
PATCH 334/366 HID: clamp input to logical range if no null state
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Tomasz Kramkowski <[email protected]>
commit c3883fe06488a483658ba5d849b70e49bee15e7c upstream.
This patch fixes an issue in drivers/hid/hid-input.c where values outside of the logical range are not clamped when "null state" bit of the input control is not set.
This was discussed on the lists [1] and this change stems from the fact due to the ambiguity of the HID specification it might be appropriate to follow Microsoft's own interpretation of the specification. As noted in Microsoft's documentation [2] in the section titled "Required HID usages for digitizers" it is noted that values reported outside the logical range "will be considered as invalid data and the value will be changed to the nearest boundary value (logical min/max)."
This patch fixes an issue where the (1292:4745) Innomedia INNEX GENESIS/ATARI reports out of range values for its X and Y axis of the DPad which, due to the null state bit being unset, are forwarded to userspace as is. Now these values will get clamped to the logical range before being forwarded to userspace. This device was also used to test this patch.
This patch expands on commit 3f3752705dbd ("HID: reject input outside logical range only if null state is set").
[1]: http://lkml.kernel.org/r/[email protected]
[2]: https://msdn.microsoft.com/en-us/library/windows/hardware/dn672278(v=vs.85).asp
--- drivers/hid/hid-input.c | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-)
drivers/hid/hid-input.c +14 -7
@@ -1087,19 +1087,26 @@ void hidinput_hid_event(struct hid_devic/* * Ignore out-of-range values as per HID specification, -* section 5.10 and 6.2.25. +* section 5.10 and 6.2.25, when NULL state bit is present. +* When it's not, clamp the value to match Microsoft's input +* driver as mentioned in "Required HID usages for digitizers": +* https://msdn.microsoft.com/en-us/library/windows/hardware/dn672278(v=vs.85).asp * * The logical_minimum < logical_maximum check is done so that we * don't unintentionally discard values sent by devices which * don't specify logical min and max. */ if ((field->flags &HID_MAIN_ITEM_VARIABLE ) && - (field->flags &HID_MAIN_ITEM_NULL_STATE ) && - (field->logical_minimum < field->logical_maximum) && - (value < field->logical_minimum || - value > field->logical_maximum)) { -dbg_hid ("Ignoring out-of-range value %x\n" , value); -return ; + (field->logical_minimum < field->logical_maximum)) { +if (field->flags &HID_MAIN_ITEM_NULL_STATE && + (value < field->logical_minimum || + value > field->logical_maximum)) { +dbg_hid ("Ignoring out-of-range value %x\n" , value); +return ; + } + value =clamp (value, + field->logical_minimum, + field->logical_maximum); }/*
PATCH 335/366 usbip: stub_rx: fix static checker warning on unnecessary checks
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Shuah Khan <[email protected]>
commit 10c90120930628e8b959bf58d4a0aaef3ae5d945 upstream.
Fix the following static checker warnings:
The patch c6688ef9f297: "usbip: fix stub_rx: harden CMD_SUBMIT path to handle malicious input" from Dec 7, 2017, leads to the following static checker warning:
drivers/usb/usbip/stub_rx.c:346 get_pipe()
warn: impossible condition
'(pdu->u.cmd_submit.transfer_buffer_length > ((~0 >> 1))) => (s32min-s32max > s32max)'
drivers/usb/usbip/stub_rx.c:486 stub_recv_cmd_submit()
warn: always true condition
'(pdu->u.cmd_submit.transfer_buffer_length <= ((~0 >> 1))) => (s32min-s32max <= s32max)'
--- drivers/staging/usbip/stub_rx.c | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-)
drivers/staging/usbip/stub_rx.c +1 -10
@@ -353,14 +353,6 @@ static int get_pipe(struct stub_device * epd = &ep->desc; -/* validate transfer_buffer_length */ -if (pdu->u.cmd_submit.transfer_buffer_length >INT_MAX ) { -dev_err (&sdev->udev->dev, -"CMD_SUBMIT: -EMSGSIZE transfer_buffer_length %d\n" , - pdu->u.cmd_submit.transfer_buffer_length); -return -1 ; - } -if (usb_endpoint_xfer_control (epd)) {if (dir ==USBIP_DIR_OUT )return usb_sndctrlpipe (udev, epnum);
@@ -494,8 +486,7 @@ static void stub_recv_cmd_submit(struct }/* allocate urb transfer buffer, if needed */ -if (pdu->u.cmd_submit.transfer_buffer_length >0 && - pdu->u.cmd_submit.transfer_buffer_length <=INT_MAX ) { +if (pdu->u.cmd_submit.transfer_buffer_length >0 ) { priv->urb->transfer_buffer =kzalloc (pdu->u.cmd_submit.transfer_buffer_length,GFP_KERNEL );
PATCH 336/366 gcov: add support for GCC 5.1
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Lorenzo Stoakes <[email protected]>
commit 3e44c471a2dab210f7e9b1e5f7d4d54d52df59eb upstream.
Fix kernel gcov support for GCC 5.1. Similar to commit a992bf836f9 ("gcov: add support for GCC 4.9"), this patch takes into account the existence of a new gcov counter (see gcc's gcc/gcov-counter.def.)
Firstly, it increments GCOV_COUNTERS (to 10), which makes the data structure struct gcov_info compatible with GCC 5.1.
Secondly, a corresponding counter function __gcov_merge_icall_topn (Top N value tracking for indirect calls) is included in base.c with the other gcov counters unused for kernel profiling.
--- kernel/gcov/base.c | 6 ++++++ kernel/gcov/gcc_4_7.c | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-)
kernel/gcov/base.c +6 -0
@@ -91,6 +91,12 @@ void __gcov_merge_time_profile(gcov_type }EXPORT_SYMBOL (__gcov_merge_time_profile); +void __gcov_merge_icall_topn (gcov_type *counters,unsigned int n_counters) +{ +/* Unused. */ +} +EXPORT_SYMBOL (__gcov_merge_icall_topn); +/** * gcov_enable_events - enable event reporting through gcov_event() *
kernel/gcov/gcc_4_7.c +3 -1
@@ -18,7 +18,9 @@#include <linux/vmalloc.h> #include "gcov.h" -#if __GNUC__ ==4 && __GNUC_MINOR__ >=9 +#if __GNUC__ ==5 && __GNUC_MINOR__ >=1 +#define GCOV_COUNTERS 10 +#elif __GNUC__ ==4 && __GNUC_MINOR__ >=9 #define GCOV_COUNTERS 9#else #define GCOV_COUNTERS 8
PATCH 337/366 gcov: add support for gcc version >= 6
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Florian Meier <[email protected]>
commit d02038f972538b93011d78c068f44514fbde0a8c upstream.
--- kernel/gcov/gcc_4_7.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/gcov/gcc_4_7.c +1 -1
@@ -18,7 +18,7 @@#include <linux/vmalloc.h> #include "gcov.h" -#if __GNUC__ ==5 && __GNUC_MINOR__ >=1 +#if (__GNUC__ >5 ) || (__GNUC__ ==5 && __GNUC_MINOR__ >=1 )#define GCOV_COUNTERS 10#elif __GNUC__ ==4 && __GNUC_MINOR__ >=9 #define GCOV_COUNTERS 9
PATCH 338/366 gcov: support GCC 7.1
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Martin Liska <[email protected]>
commit 05384213436ab690c46d9dfec706b80ef8d671ab upstream.
Starting from GCC 7.1, __gcov_exit is a new symbol expected to be implemented in a profiling runtime.
--- kernel/gcov/base.c | 6 ++++++ kernel/gcov/gcc_4_7.c | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-)
kernel/gcov/base.c +6 -0
@@ -97,6 +97,12 @@ void __gcov_merge_icall_topn(gcov_type * }EXPORT_SYMBOL (__gcov_merge_icall_topn); +void __gcov_exit (void ) +{ +/* Unused. */ +} +EXPORT_SYMBOL (__gcov_exit); +/** * gcov_enable_events - enable event reporting through gcov_event() *
kernel/gcov/gcc_4_7.c +3 -1
@@ -18,7 +18,9 @@#include <linux/vmalloc.h> #include "gcov.h" -#if (__GNUC__ >5 ) || (__GNUC__ ==5 && __GNUC_MINOR__ >=1 ) +#if (__GNUC__ >=7 ) +#define GCOV_COUNTERS 9 +#elif (__GNUC__ >5 ) || (__GNUC__ ==5 && __GNUC_MINOR__ >=1 )#define GCOV_COUNTERS 10#elif __GNUC__ ==4 && __GNUC_MINOR__ >=9 #define GCOV_COUNTERS 9
PATCH 339/366 KVM: x86: fix escape of guest dr6 to the host
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Wanpeng Li <[email protected]>
commit efdab992813fb2ed825745625b83c05032e9cda2 upstream.
syzkaller reported:
WARNING: CPU: 0 PID: 12927 at arch/x86/kernel/traps.c:780 do_debug+0x222/0x250
CPU: 0 PID: 12927 Comm: syz-executor Tainted: G OE 4.15.0-rc2+ #16
RIP: 0010:do_debug+0x222/0x250
Call Trace:
<#DB>
debug+0x3e/0x70
RIP: 0010:copy_user_enhanced_fast_string+0x10/0x20
</#DB>
_copy_from_user+0x5b/0x90
SyS_timer_create+0x33/0x80
entry_SYSCALL_64_fastpath+0x23/0x9aThe testcase sets a watchpoint (with perf_event_open) on a buffer that is passed to timer_create() as the struct sigevent argument. In timer_create(), copy_from_user()'s rep movsb triggers the BP. The testcase also sets the debug registers for the guest.
However, KVM only restores host debug registers when the host has active watchpoints, which triggers a race condition when running the testcase with multiple threads. The guest's DR6.BS bit can escape to the host before another thread invokes timer_create(), and do_debug() complains.
The fix is to respect do_debug()'s dr6 invariant when leaving KVM.
--- arch/x86/kvm/x86.c | 6 ++++++ 1 file changed, 6 insertions(+)
arch/x86/kvm/x86.c +6 -0
@@ -2892,6 +2892,12 @@ void kvm_arch_vcpu_put(struct kvm_vcpu * kvm_x86_ops->vcpu_put (vcpu);kvm_put_guest_fpu (vcpu); vcpu->arch.last_host_tsc =native_read_tsc (); +/* +* If userspace has set any breakpoints or watchpoints, dr6 is restored +* on every vmexit, but if not, we might have a stale dr6 from the +* guest. do_debug expects dr6 to be cleared after it runs, do the same. +*/ +set_debugreg (0 ,6 ); } static int kvm_vcpu_ioctl_get_lapic(struct kvm_vcpu *vcpu,
PATCH 340/366 iio: iio-trig-periodic-rtc: Free trigger resource correctly
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Ben Hutchings <[email protected]>
This is based on upstream commit 10e840dfb0b7, which did not touch the iio-trig-periodic-rtc driver because it has been removed upstream.
The following explanation comes from that commit:
These stand-alone trigger drivers were using iio_trigger_put() where they should have been using iio_trigger_free(). The iio_trigger_put() adds a module_put which is bad since they never did a module_get.
In the sysfs driver, module_get/put's are used as triggers are added & removed. This extra module_put() occurs on an error path in the probe routine (probably rare).
In the bfin-timer & interrupt trigger drivers, the module resources are not explicitly managed, so it's doing a put on something that was never get'd. It occurs on the probe error path and on the remove path (not so rare).
Tested with the sysfs trigger driver.
The bfin & interrupt drivers were build tested & inspected only.
This was build tested only.
--- drivers/staging/iio/trigger/iio-trig-periodic-rtc.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/staging/iio/trigger/iio-trig-periodic-rtc.c +3 -3
@@ -123,7 +123,7 @@ static int iio_trig_periodic_rtc_probe(s trig_info =kzalloc (sizeof (*trig_info),GFP_KERNEL );if (!trig_info) { ret = -ENOMEM ; - goto error_put_trigger_and_remove_from_list; + goto error_free_trigger_and_remove_from_list; }iio_trigger_set_drvdata (trig, trig_info); trig->ops = &iio_prtc_trigger_ops;
@@ -151,9 +151,9 @@ error_close_rtc:rtc_class_close (trig_info->rtc); error_free_trig_info:kfree (trig_info); -error_put_trigger_and_remove_from_list: +error_free_trigger_and_remove_from_list:list_del (&trig->alloc_list); -iio_trigger_put (trig); +iio_trigger_free (trig); error_free_completed_registrations:list_for_each_entry_safe (trig, trig2,
PATCH 341/366 MIPS: asm: compiler: Add new macros to set ISA and arch asm annotations
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Markos Chandras <[email protected]>
commit be5136988e25ae0dc8379fcb937efc63d87aba9e upstream.
There are certain places where the code uses .set mips32 or .set mips64 or .set arch=r4000. In preparation of MIPS R6 support, and in order to use as less #ifdefs as possible, we define new macros to set similar annotations for MIPS R6.
[bwh: Backported to 3.16: We don't support MIPS R6 but I have applied a
commit that uses MIPS_ISA_LEVEL_RAW. Add the R2 definitions only.]
--- arch/mips/include/asm/compiler.h | 13 +++++++++++++ 1 file changed, 13 insertions(+)
arch/mips/include/asm/compiler.h +6 -0
@@ -16,4 +16,10 @@#define GCC_REG_ACCUM "accum"#endif +/* MIPS64 is a superset of MIPS32 */ +#define MIPS_ISA_LEVEL "mips64r2" +#define MIPS_ISA_ARCH_LEVEL "arch=r4000" +#define MIPS_ISA_LEVEL_RAW mips64r2 +#define MIPS_ISA_ARCH_LEVEL_RAW MIPS_ISA_LEVEL_RAW +#endif /* _ASM_COMPILER_H */
PATCH 342/366 clk: si5351: Constify clock names and struct regmap_config
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski <[email protected]>
commit 8234caed27f7bce141c9fb1f7e76c91a2a66d248 upstream.
The regmap_config struct may be const because it is not modified by the driver and regmap_init() accepts pointer to const.
Replace doubled const in the arrays of clock names with proper const pointer to const data. This fixes the warnings:
drivers/clk/clk-si5351.c:71:25: warning: duplicate const drivers/clk/clk-si5351.c:74:25: warning: duplicate const drivers/clk/clk-si5351.c:77:25: warning: duplicate const drivers/clk/clk-si5351.c:80:25: warning: duplicate const
--- drivers/clk/clk-si5351.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/clk/clk-si5351.c +5 -5
@@ -68,16 +68,16 @@ struct si5351_driver_data {struct si5351_hw_data *clkout; }; -static const char const *si5351_input_names[] = { +static const char *const si5351_input_names[] = {"xtal" ,"clkin" }; -static const char const *si5351_pll_names[] = { +static const char *const si5351_pll_names[] = {"plla" ,"pllb" ,"vxco" }; -static const char const *si5351_msynth_names[] = { +static const char *const si5351_msynth_names[] = {"ms0" ,"ms1" ,"ms2" ,"ms3" ,"ms4" ,"ms5" ,"ms6" ,"ms7" }; -static const char const *si5351_clkout_names[] = { +static const char *const si5351_clkout_names[] = {"clk0" ,"clk1" ,"clk2" ,"clk3" ,"clk4" ,"clk5" ,"clk6" ,"clk7" };
@@ -207,7 +207,7 @@ static bool si5351_regmap_is_writeable(sreturn true; } -static struct regmap_config si5351_regmap_config = { +static const struct regmap_config si5351_regmap_config = { .reg_bits =8 , .val_bits =8 , .cache_type =REGCACHE_RBTREE ,
PATCH 343/366 net/wireless/brcm80211/brcmfmac: Make return type and name reflect actual semantics
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Rasmus Villemoes <[email protected]>
commit e843bb199ba58ce5d1364d4c82fcf6975f08eec2 upstream.
Applying ++ to a bool is equivalent to setting it true, regardless of its initial value (bools are not uint1_t). Hence the function wl_get_vif_state_all can only ever return true/false. The only in-tree caller uses its return value as a boolean. So update its return type, and since the list traversal and bit testing have no side effects, just return true immediately. Its return value tells if any vif is in the specified state, so also rename it to brcmf_get_vif_state_any.
--- drivers/net/wireless/brcm80211/brcmfmac/p2p.c | 2 +- drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c | 7 +++---- drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-)
drivers/net/wireless/brcm80211/brcmfmac/p2p.c +1 -1
@@ -706,7 +706,7 @@ static s32 brcmf_p2p_escan(struct brcmf_ active =P2PAPI_SCAN_SOCIAL_DWELL_TIME_MS ; else if (num_chans == AF_PEER_SEARCH_CNT) active =P2PAPI_SCAN_AF_SEARCH_DWELL_TIME_MS ; - else if (wl_get_vif_state_all(p2p->cfg, BRCMF_VIF_STATUS_CONNECTED)) + else if (brcmf_get_vif_state_any(p2p->cfg, BRCMF_VIF_STATUS_CONNECTED)) active =-1 ; else active =P2PAPI_SCAN_DWELL_TIME_MS ;
drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c +3 -4
@@ -5647,16 +5647,15 @@ enum nl80211_iftype brcmf_cfg80211_get_ireturn wdev->iftype; } -u32 wl_get_vif_state_all (struct brcmf_cfg80211_info *cfg,unsigned long state) +bool brcmf_get_vif_state_any (struct brcmf_cfg80211_info *cfg,unsigned long state) {struct brcmf_cfg80211_vif *vif; -bool result =0 ;list_for_each_entry (vif, &cfg->vif_list, list) {if (test_bit (state, &vif->sme_state)) - result++; +return true; } -return result; +return false; } static inline bool vif_event_equals(struct brcmf_cfg80211_vif_event *event,
drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.h +1 -1
@@ -477,7 +477,7 @@ const struct brcmf_tlv * brcmf_parse_tlvs(const void *buf, int buflen, uint key);u16 channel_to_chanspec (struct brcmu_d11inf *d11inf,struct ieee80211_channel *ch); -u32 wl_get_vif_state_all (struct brcmf_cfg80211_info *cfg,unsigned long state); +bool brcmf_get_vif_state_any (struct brcmf_cfg80211_info *cfg,unsigned long state);void brcmf_cfg80211_arm_vif_event (struct brcmf_cfg80211_info *cfg,struct brcmf_cfg80211_vif *vif);bool brcmf_cfg80211_vif_event_armed (struct brcmf_cfg80211_info *cfg);
PATCH 344/366 ir-core: fix gcc-7 warning on bool arithmetic
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Arnd Bergmann <[email protected]>
commit bd7e31bbade02bc1e92aa00d5cf2cee2da66838a upstream.
gcc-7 suggests that an expression using a bitwise not and a bitmask on a 'bool' variable is better written using boolean logic:
drivers/media/rc/imon.c: In function 'imon_incoming_scancode':drivers/media/rc/imon.c:1725:22: error: '~' on a boolean expression [-Werror=bool-operation]
ictx->pad_mouse = ~(ictx->pad_mouse) & 0x1;
^drivers/media/rc/imon.c:1725:22: note: did you mean to use logical not?
I agree.
--- drivers/media/rc/imon.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/media/rc/imon.c +1 -1
@@ -1530,7 +1530,7 @@ static void imon_incoming_packet(structif (kc ==KEY_KEYBOARD && !ictx->release_code) { ictx->last_keycode = kc;if (!nomouse) { - ictx->pad_mouse = ~(ictx->pad_mouse) &0x1 ; + ictx->pad_mouse = !ictx->pad_mouse;dev_dbg (dev,"toggling to %s mode\n" , ictx->pad_mouse ?"mouse" :"keyboard" );spin_unlock_irqrestore (&ictx->kc_lock, flags);
PATCH 345/366 p54: memset(0) whole array
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Jiri Slaby <[email protected]>
commit 6f17581788206444cbbcdbc107498f85e9765e3d upstream.
gcc 7 complains:drivers/net/wireless/intersil/p54/fwio.c: In function 'p54_scan':drivers/net/wireless/intersil/p54/fwio.c:491:4: warning: 'memset' used with length equal to number of elements without multiplication by element size [-Wmemset-elt-size]
Fix that by passing the correct size to memset.
--- drivers/net/wireless/p54/fwio.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/p54/fwio.c +1 -1
@@ -486,7 +486,7 @@ int p54_scan(struct p54_common *priv, u1 entry +=sizeof (__le16); chan->pa_points_per_curve =8 ; -memset (chan->curve_data,0 ,sizeof (*chan->curve_data)); +memset (chan->curve_data,0 ,sizeof (chan->curve_data));memcpy (chan->curve_data, entry,sizeof (struct p54_pa_curve_data_sample ) *min ((u8 )8 , curve_data->points_per_channel));
PATCH 346/366 kexec: Fix make headers_check
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Geoff Levand <[email protected]>
commit 9dc5c05f45ca8101025046cda7f8aca8835204f2 upstream.
Remove the unneded declaration for a kexec_load() routine.
Fixes errors like these when running 'make headers_check':
include/uapi/linux/kexec.h: userspace cannot reference function or variable defined in the kernel
Paul said:
: The kexec_load declaration isn't very useful for userspace, see the patch
: I submitted in http://lkml.kernel.org/r/1389791824.17407.9.camel@x220 .
: And After my attempt the export of that declaration has also been
: discussed in
: http://lkml.kernel.org/r/115373b6ac68ee7a305975896e1c4971e8e51d4c.1408731991.git.geoff@infradead.org
:
: In that last discussion no one has been able to point to an actual user of
: it. So, as far as I can tell, no one actually uses it. Which makes
: sense, because including this header by itself doesn't give one access to
: a useful definition of kexec_load. So why bother with the declaration?
--- include/uapi/linux/kexec.h | 6 ------ 1 file changed, 6 deletions(-)
include/uapi/linux/kexec.h +0 -6
@@ -44,12 +44,6 @@ struct kexec_segment {size_t memsz; }; -/* Load a new kernel image as described by the kexec_segment array -* consisting of passed number of segments at the entry-point address. -* The flags allow different useage types. -*/ -extern int kexec_load (void *,size_t ,struct kexec_segment *, -unsigned long int );#endif /* __KERNEL__ */ #endif /* _UAPILINUX_KEXEC_H */
PATCH 347/366 arm64: use linux/types.h in kvm.h
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Arnd Bergmann <[email protected]>
commit d19279154b3fff9adff96b54d1a77dfb8f01e3da upstream.
We should always use linux/types.h instead of asm/types.h for consistency, and Kbuild actually warns about it:
./usr/include/asm/kvm.h:35: include of <linux/types.h> is preferred over <asm/types.h>
This patch does as Kbuild asks us.
--- arch/arm64/include/uapi/asm/kvm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/include/uapi/asm/kvm.h +1 -1
@@ -32,7 +32,7 @@#ifndef __ASSEMBLY__#include <linux/psci.h> -#include <asm/types.h> +#include <linux/types.h> #include <asm/ptrace.h> #define __KVM_HAVE_GUEST_DEBUG
PATCH 348/366 MIPS: asmmacro: Ensure 64-bit FP registers are used with MSA
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Markos Chandras <[email protected]>
commit 2bd7bc254ab1f45269db6dd7957d63b713817408 upstream.
This silences warnings like the following one when building with the latest binutils:
arch/mips/kernel/genex.S: Assembler messages:arch/mips/kernel/genex.S:438: Warning: the `msa' extension requires 64-bit FPRs
[[email protected]: Markos says binutils 2.25 and some 2.24 snapshots are affected.]
Patchwork: https://patchwork.linux-mips.org/patch/9745/
--- arch/mips/include/asm/asmmacro.h | 11 +++++++++++ 1 file changed, 11 insertions(+)
arch/mips/include/asm/asmmacro.h +11 -0
@@ -209,9 +209,13 @@ .endm#ifdef TOOLCHAIN_SUPPORTS_MSA +/* preprocessor replaces the fp in ".set fp=64" with $30 otherwise */ +#undef fp + .macro _cfcmsa rd, cs .set push .set mips32r2 + .set fp=64 .set msa cfcmsa \rd, $\cs .set pop
@@ -220,6 +224,7 @@ .macro _ctcmsa cd, rs .set push .set mips32r2 + .set fp=64 .set msa ctcmsa $\cd, \rs .set pop
@@ -228,6 +233,7 @@ .macro ld_d wd, off, base .set push .set mips32r2 + .set fp=64 .set msa ld.d $w\wd, \off(\base) .set pop
@@ -236,6 +242,7 @@ .macro st_d wd, off, base .set push .set mips32r2 + .set fp=64 .set msa st.d $w\wd, \off(\base) .set pop
@@ -244,6 +251,7 @@ .macro copy_u_w ws, n .set push .set mips32r2 + .set fp=64 .set msa copy_u.w $1, $w\ws[\n] .set pop
@@ -252,6 +260,7 @@ .macro copy_u_d ws, n .set push .set mips64r2 + .set fp=64 .set msa copy_u.d $1, $w\ws[\n] .set pop
@@ -260,6 +269,7 @@ .macro insert_w wd, n .set push .set mips32r2 + .set fp=64 .set msa insert.w $w\wd[\n], $1 .set pop
@@ -268,6 +278,7 @@ .macro insert_d wd, n .set push .set mips64r2 + .set fp=64 .set msa insert.d $w\wd[\n], $1 .set pop
PATCH 349/366 x86/apic: Fix build failure with X86_IO_APIC disabled
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Ben Hutchings <[email protected]>
My backport of commit 2e63ad4bd5dd "x86/apic: Do not init irq remapping if ioapic is disabled" added an unconditional use of skip_ioapic_setup. Enabling X86_LOCAL_APIC but not X86_IO_APIC results in a build failure.
This configuration was made impossible by commit b1da1e715d4f "x86/Kconfig: Simplify X86_IO_APIC dependencies", but that seems to depend on additional changes that aren't suitable for stable.
The function that was changed, enable_IR_x2apic(), is only used in 64-bit configurations where CONFIG_X86_IO_APIC is always enabled. So extend the #ifdef CONFIG_X86_64 section to include this function.
---
arch/x86/kernel/apic/apic.c +2 -1
@@ -1609,6 +1609,8 @@ int __init enable_IR(void)return -1 ; } +#ifdef CONFIG_X86_64 +void __init enable_IR_x2apic (void ) {unsigned long flags;
@@ -1683,7 +1685,6 @@ skip_x2apic:local_irq_restore (flags); } -#ifdef CONFIG_X86_64 /* * Detect and enable local APICs on non-SMP boards. * Original code written by Keir Fraser.
PATCH 350/366 sched/topology: Make local variables static
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: zhong jiang <[email protected]>
commit ace8031099f91480799b5929b4cccf2dcacc5136 upstream.
Fix the following warnings:
kernel/sched/topology.c:10:15: warning: symbol 'sched_domains_tmpmask' was not declared. Should it be static? kernel/sched/topology.c:11:15: warning: symbol 'sched_domains_tmpmask2' was not declared. Should it be static?
---
kernel/sched/core.c +1 -1
@@ -5286,7 +5286,7 @@ early_initcall(migration_init);#ifdef CONFIG_SMP static cpumask_var_t sched_domains_tmpmask;/* sched_domains_mutex */ -cpumask_var_t sched_domains_tmpmask2; +static cpumask_var_t sched_domains_tmpmask2;#ifdef CONFIG_SCHED_DEBUG
PATCH 351/366 usb: misc: usb3503: Update error code in print message
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Tushar Behera <[email protected]>
commit ec5734c41bee2ee7c938a8f34853d31cada7e67a upstream.
'err' is uninitialized, rather print the error code directly.
This also fixes following warning.drivers/usb/misc/usb3503.c: In function ‘usb3503_probe’:drivers/usb/misc/usb3503.c:195:11: warning: ‘err’ may be used uninitialized in this function [-Wmaybe-uninitialized]
dev_err(dev, "unable to request refclk (%d)\n", err);
--- drivers/usb/misc/usb3503.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/usb/misc/usb3503.c +2 -1
@@ -192,7 +192,8 @@ static int usb3503_probe(struct usb3503 clk =devm_clk_get (dev,"refclk" );if (IS_ERR (clk) &&PTR_ERR (clk) != -ENOENT ) { -dev_err (dev,"unable to request refclk (%d)\n" , err); +dev_err (dev,"unable to request refclk (%ld)\n" , +PTR_ERR (clk));return PTR_ERR (clk); }
PATCH 352/366 perf tools: Move syscall number fallbacks from perf-sys.h to tools/arch/x86/include/asm/
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Arnaldo Carvalho de Melo <[email protected]>
commit cec07f53c398f22576df77052c4777dc13f14962 upstream.
And remove the empty tools/arch/x86/include/asm/unistd_{32,64}.h files introduced by eae7a755ee81 ("perf tools, x86: Build perf on older user-space as well").
This way we get closer to mirroring the kernel for cases where __NR_ can't be found for some include path/_GNU_SOURCE/whatever scenario.
[bwh: Backported to 3.16:
- Also remove the deleted headers from LIB_H in Makefile.perf
- Adjust context]
---
tools/arch/x86/include/asm/unistd_32.h new file +9 -0
@@ -0,0 +1,9 @@ +#ifndef __NR_perf_event_open +# define __NR_perf_event_open 336 +#endif +#ifndef __NR_futex +# define __NR_futex 240 +#endif +#ifndef __NR_gettid +# define __NR_gettid 224 +#endif
tools/arch/x86/include/asm/unistd_64.h new file +9 -0
@@ -0,0 +1,9 @@ +#ifndef __NR_perf_event_open +# define __NR_perf_event_open 298 +#endif +#ifndef __NR_futex +# define __NR_futex 202 +#endif +#ifndef __NR_gettid +# define __NR_gettid 186 +#endif
tools/perf/config/Makefile +1 -0
@@ -252,6 +252,7 @@ CFLAGS += -I$(src-perf)/arch/$(ARCH)/inc CFLAGS += -I$(srctree)/tools/include/ CFLAGS += -I$(srctree)/arch/$(ARCH)/include/uapi CFLAGS += -I$(srctree)/arch/$(ARCH)/include +CFLAGS += -I$(srctree)/tools/arch/$(ARCH)/include CFLAGS += -I$(srctree)/include/uapi CFLAGS += -I$(srctree)/include
tools/perf/perf-sys.h +0 -18
@@ -14,15 +14,6 @@#define rmb () asm volatile("lock; addl $0,0(%%esp)" ::: "memory")#define cpu_relax () asm volatile("rep; nop" ::: "memory");#define CPUINFO_PROC "model name" -#ifndef __NR_perf_event_open -# define __NR_perf_event_open 336 -#endif -#ifndef __NR_futex -# define __NR_futex 240 -#endif -#ifndef __NR_gettid -# define __NR_gettid 224 -#endif #endif #if defined(__x86_64__)
@@ -31,15 +22,6 @@#define rmb () asm volatile("lfence" ::: "memory")#define cpu_relax () asm volatile("rep; nop" ::: "memory");#define CPUINFO_PROC "model name" -#ifndef __NR_perf_event_open -# define __NR_perf_event_open 298 -#endif -#ifndef __NR_futex -# define __NR_futex 202 -#endif -#ifndef __NR_gettid -# define __NR_gettid 186 -#endif #endif #ifdef __powerpc__
tools/perf/util/include/asm/unistd_32.h deleted +0 -1
@@ -1 +0,0 @@ -
tools/perf/util/include/asm/unistd_64.h deleted +0 -1
@@ -1 +0,0 @@ -
tools/perf/Makefile.perf +0 -2
@@ -239,8 +239,6 @@ LIB_H += util/include/asm/uaccess.h LIB_H += util/include/dwarf-regs.h LIB_H += util/include/asm/dwarf2.h LIB_H += util/include/asm/cpufeature.h -LIB_H += util/include/asm/unistd_32.h -LIB_H += util/include/asm/unistd_64.h LIB_H += perf.h LIB_H += util/annotate.h LIB_H += util/cache.h
PATCH 353/366 perf tools: define _DEFAULT_SOURCE for glibc_2.20
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Chanho Park <[email protected]>
commit 512fe365373b9c95a70b4b6357503ee74d27214f upstream.
_BSD_SOURCE was deprecated in favour of _DEFAULT_SOURCE since glibc 2.20[1]. To avoid build warning on glibc2.20, _DEFAULT_SOURCE should also be defined.
[1]: https://sourceware.org/glibc/wiki/Release/2.20
--- tools/perf/util/util.h | 2 ++ 1 file changed, 2 insertions(+)
tools/perf/util/util.h +2 -0
@@ -39,6 +39,8 @@#define _ALL_SOURCE 1#define _BSD_SOURCE 1 +/* glibc 2.20 deprecates _BSD_SOURCE in favour of _DEFAULT_SOURCE */ +#define _DEFAULT_SOURCE 1#define HAS_BOOL #include <unistd.h>
PATCH 354/366 perf script: Use readdir() instead of deprecated readdir_r()
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Arnaldo Carvalho de Melo <[email protected]>
commit a5e8e825bd1704c488bf6a46936aaf3b9f203d6a upstream.
The readdir() function is thread safe as long as just one thread uses a DIR, which is the case in 'perf script', so, to avoid breaking the build with glibc-2.23.90 (upcoming 2.24), use it instead of readdir_r().
See: http://man7.org/linux/man-pages/man3/readdir.3.html
"However, in modern implementations (including the glibc implementation), concurrent calls to readdir() that specify different directory streams are thread-safe. In cases where multiple threads must read from the same directory stream, using readdir() with external synchronization is still preferable to the use of the deprecated readdir_r(3) function."
Noticed while building on a Fedora Rawhide docker container.
--- tools/perf/builtin-script.c | 70 ++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 36 deletions(-)
tools/perf/builtin-script.c +34 -36
@@ -1061,21 +1061,19 @@ static int is_directory(const char *basereturn S_ISDIR (st.st_mode); } -#define for_each_lang (scripts_path, scripts_dir, lang_dirent, lang_next)\ - while (!readdir_r(scripts_dir, &lang_dirent, &lang_next) && \ - lang_next) \ - if ((lang_dirent.d_type == DT_DIR || \ - (lang_dirent.d_type == DT_UNKNOWN && \ - is_directory(scripts_path, &lang_dirent))) && \ - (strcmp(lang_dirent.d_name, ".")) && \ - (strcmp(lang_dirent.d_name, ".."))) - -#define for_each_script (lang_path, lang_dir, script_dirent, script_next)\ - while (!readdir_r(lang_dir, &script_dirent, &script_next) && \ - script_next) \ - if (script_dirent.d_type != DT_DIR && \ - (script_dirent.d_type != DT_UNKNOWN || \ - !is_directory(lang_path, &script_dirent))) +#define for_each_lang (scripts_path, scripts_dir, lang_dirent) \ + while ((lang_dirent = readdir(scripts_dir)) != NULL) \ + if ((lang_dirent->d_type == DT_DIR || \ + (lang_dirent->d_type == DT_UNKNOWN && \ + is_directory(scripts_path, lang_dirent))) && \ + (strcmp(lang_dirent->d_name, ".")) && \ + (strcmp(lang_dirent->d_name, ".."))) + +#define for_each_script (lang_path, lang_dir, script_dirent) \ + while ((script_dirent = readdir(lang_dir)) != NULL) \ + if (script_dirent->d_type != DT_DIR && \ + (script_dirent->d_type != DT_UNKNOWN || \ + !is_directory(lang_path, script_dirent)))#define RECORD_SUFFIX "-record"
@@ -1221,7 +1219,7 @@ static int list_available_scripts(const const char *s __maybe_unused, int unset __maybe_unused) { -struct dirent *script_next, *lang_next, script_dirent, lang_dirent; +struct dirent *script_dirent, *lang_dirent;char scripts_path[MAXPATHLEN ];DIR *scripts_dir, *lang_dir;char script_path[MAXPATHLEN ];
@@ -1236,19 +1234,19 @@ static int list_available_scripts(constif (!scripts_dir)return -1 ; -for_each_lang (scripts_path, scripts_dir, lang_dirent, lang_next) { +for_each_lang (scripts_path, scripts_dir, lang_dirent) {snprintf (lang_path,MAXPATHLEN ,"%s/%s/bin" , scripts_path, - lang_dirent.d_name); + lang_dirent->d_name); lang_dir =opendir (lang_path);if (!lang_dir)continue ; -for_each_script (lang_path, lang_dir, script_dirent, script_next) { - script_root =get_script_root (&script_dirent,REPORT_SUFFIX ); +for_each_script (lang_path, lang_dir, script_dirent) { + script_root =get_script_root (script_dirent,REPORT_SUFFIX );if (script_root) { desc =script_desc__findnew (script_root);snprintf (script_path,MAXPATHLEN ,"%s/%s" , - lang_path, script_dirent.d_name); + lang_path, script_dirent->d_name);read_script_info (desc, script_path);free (script_root); }
@@ -1336,7 +1334,7 @@ static int check_ev_match(char *dir_name*/ int find_scripts (char **scripts_array,char **scripts_path_array) { -struct dirent *script_next, *lang_next, script_dirent, lang_dirent; +struct dirent *script_dirent, *lang_dirent;char scripts_path[MAXPATHLEN ], lang_path[MAXPATHLEN ];DIR *scripts_dir, *lang_dir;struct perf_session *session;
@@ -1359,9 +1357,9 @@ int find_scripts(char **scripts_array, creturn -1 ; } -for_each_lang (scripts_path, scripts_dir, lang_dirent, lang_next) { +for_each_lang (scripts_path, scripts_dir, lang_dirent) {snprintf (lang_path,MAXPATHLEN ,"%s/%s" , scripts_path, - lang_dirent.d_name); + lang_dirent->d_name);#ifdef NO_LIBPERL if (strstr (lang_path,"perl" ))continue ;
@@ -1375,16 +1373,16 @@ int find_scripts(char **scripts_array, cif (!lang_dir)continue ; -for_each_script (lang_path, lang_dir, script_dirent, script_next) { +for_each_script (lang_path, lang_dir, script_dirent) {/* Skip those real time scripts: xxxtop.p[yl] */ -if (strstr (script_dirent.d_name,"top." )) +if (strstr (script_dirent->d_name,"top." ))continue ;sprintf (scripts_path_array[i],"%s/%s" , lang_path, - script_dirent.d_name); - temp =strchr (script_dirent.d_name,'.' ); + script_dirent->d_name); + temp =strchr (script_dirent->d_name,'.' );snprintf (scripts_array[i], - (temp - script_dirent.d_name) +1 , -"%s" , script_dirent.d_name); + (temp - script_dirent->d_name) +1 , +"%s" , script_dirent->d_name);if (check_ev_match (lang_path, scripts_array[i], session))
@@ -1402,7 +1400,7 @@ int find_scripts(char **scripts_array, cstatic char *get_script_path (const char *script_root,const char *suffix) { -struct dirent *script_next, *lang_next, script_dirent, lang_dirent; +struct dirent *script_dirent, *lang_dirent;char scripts_path[MAXPATHLEN ];char script_path[MAXPATHLEN ];DIR *scripts_dir, *lang_dir;
@@ -1415,21 +1413,21 @@ static char *get_script_path(const charif (!scripts_dir)return NULL ; -for_each_lang (scripts_path, scripts_dir, lang_dirent, lang_next) { +for_each_lang (scripts_path, scripts_dir, lang_dirent) {snprintf (lang_path,MAXPATHLEN ,"%s/%s/bin" , scripts_path, - lang_dirent.d_name); + lang_dirent->d_name); lang_dir =opendir (lang_path);if (!lang_dir)continue ; -for_each_script (lang_path, lang_dir, script_dirent, script_next) { - __script_root =get_script_root (&script_dirent, suffix); +for_each_script (lang_path, lang_dir, script_dirent) { + __script_root =get_script_root (script_dirent, suffix);if (__script_root && !strcmp (script_root, __script_root)) {free (__script_root);closedir (lang_dir);closedir (scripts_dir);snprintf (script_path,MAXPATHLEN ,"%s/%s" , - lang_path, script_dirent.d_name); + lang_path, script_dirent->d_name);return strdup (script_path); }free (__script_root);
PATCH 355/366 perf thread_map: Use readdir() instead of deprecated readdir_r()
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Arnaldo Carvalho de Melo <[email protected]>
commit 3354cf71104de49326d19d2f9bdb1f66eea52ef4 upstream.
The readdir() function is thread safe as long as just one thread uses a DIR, which is the case in thread_map, so, to avoid breaking the build with glibc-2.23.90 (upcoming 2.24), use it instead of readdir_r().
See: http://man7.org/linux/man-pages/man3/readdir.3.html
"However, in modern implementations (including the glibc implementation), concurrent calls to readdir() that specify different directory streams are thread-safe. In cases where multiple threads must read from the same directory stream, using readdir() with external synchronization is still preferable to the use of the deprecated readdir_r(3) function."
Noticed while building on a Fedora Rawhide docker container.
--- tools/perf/util/thread_map.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
tools/perf/util/thread_map.c +4 -4
@@ -64,7 +64,7 @@ struct thread_map *thread_map__new_by_uiDIR *proc;int max_threads =32 , items, i;char path[256 ]; -struct dirent dirent, *next, **namelist =NULL ; +struct dirent *dirent, **namelist =NULL ;struct thread_map *threads =malloc (sizeof (*threads) + max_threads *sizeof (pid_t));if (threads ==NULL )
@@ -76,16 +76,16 @@ struct thread_map *thread_map__new_by_ui threads->nr =0 ; -while (!readdir_r (proc, &dirent, &next) && next) { +while ((dirent =readdir (proc)) !=NULL ) {char *end;bool grow = false;struct stat st; -pid_t pid =strtol (dirent.d_name, &end,10 ); +pid_t pid =strtol (dirent->d_name, &end,10 );if (*end)/* only interested in proper numerical dirents */ continue ; -snprintf (path,sizeof (path),"/proc/%s" , dirent.d_name); +snprintf (path,sizeof (path),"/proc/%s" , dirent->d_name);if (stat (path, &st) !=0 )continue ;
PATCH 356/366 perf tools: Use readdir() instead of deprecated readdir_r()
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Arnaldo Carvalho de Melo <[email protected]>
commit 7093b4c963cc4e344e490c774924a180602a7092 upstream.
The readdir() function is thread safe as long as just one thread uses a DIR, which is the case when synthesizing events for pre-existing threads by traversing /proc, so, to avoid breaking the build with glibc-2.23.90 (upcoming 2.24), use it instead of readdir_r().
See: http://man7.org/linux/man-pages/man3/readdir.3.html
"However, in modern implementations (including the glibc implementation), concurrent calls to readdir() that specify different directory streams are thread-safe. In cases where multiple threads must read from the same directory stream, using readdir() with external synchronization is still preferable to the use of the deprecated readdir_r(3) function."
Noticed while building on a Fedora Rawhide docker container.
CC /tmp/build/perf/util/event.o
util/event.c: In function '__event__synthesize_thread':
util/event.c:466:2: error: 'readdir_r' is deprecated [-Werror=deprecated-declarations]
while (!readdir_r(tasks, &dirent, &next) && next) {
^~~~~
In file included from /usr/include/features.h:368:0,
from /usr/include/stdint.h:25,
from /usr/lib/gcc/x86_64-redhat-linux/6.0.0/include/stdint.h:9,
from /git/linux/tools/include/linux/types.h:6,
from util/event.c:1: /usr/include/dirent.h:189:12: note: declared here
--- tools/perf/util/event.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
tools/perf/util/event.c +6 -6
@@ -331,7 +331,7 @@ static int __event__synthesize_thread(un {char filename[PATH_MAX ];DIR *tasks; -struct dirent dirent, *next; +struct dirent *dirent;pid_t tgid;/* special case: only send one comm event using passed in pid */
@@ -358,12 +358,12 @@ static int __event__synthesize_thread(unreturn 0 ; } -while (!readdir_r (tasks, &dirent, &next) && next) { +while ((dirent =readdir (tasks)) !=NULL ) {char *end;int rc =0 ;pid_t _pid; - _pid =strtol (dirent.d_name, &end,10 ); + _pid =strtol (dirent->d_name, &end,10 );if (*end)continue ;
@@ -464,7 +464,7 @@ int perf_event__synthesize_threads(struc {DIR *proc;char proc_path[PATH_MAX ]; -struct dirent dirent, *next; +struct dirent *dirent;union perf_event *comm_event, *mmap_event, *fork_event;int err =-1 ;
@@ -489,9 +489,9 @@ int perf_event__synthesize_threads(strucif (proc ==NULL ) goto out_free_fork; -while (!readdir_r (proc, &dirent, &next) && next) { +while ((dirent =readdir (proc)) !=NULL ) {char *end; -pid_t pid =strtol (dirent.d_name, &end,10 ); +pid_t pid =strtol (dirent->d_name, &end,10 );if (*end)/* only interested in proper numerical dirents */ continue ;
PATCH 357/366 perf tools: Use readdir() instead of deprecated readdir_r()
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Arnaldo Carvalho de Melo <[email protected]>
commit bfc279f3d233150ff260e9e93012e14f86810648 upstream.
The readdir() function is thread safe as long as just one thread uses a DIR, which is the case when parsing tracepoint event definitions, to avoid breaking the build with glibc-2.23.90 (upcoming 2.24), use it instead of readdir_r().
See: http://man7.org/linux/man-pages/man3/readdir.3.html
"However, in modern implementations (including the glibc implementation), concurrent calls to readdir() that specify different directory streams are thread-safe. In cases where multiple threads must read from the same directory stream, using readdir() with external synchronization is still preferable to the use of the deprecated readdir_r(3) function."
Noticed while building on a Fedora Rawhide docker container.
--- tools/perf/util/parse-events.c | 60 +++++++++++++++++----------------- 1 file changed, 30 insertions(+), 30 deletions(-)
tools/perf/util/parse-events.c +31 -31
@@ -123,11 +123,11 @@ static struct event_symbol event_symbols#define PERF_EVENT_TYPE (config) __PERF_EVENT_FIELD(config, TYPE)#define PERF_EVENT_ID (config) __PERF_EVENT_FIELD(config, EVENT) -#define for_each_subsystem (sys_dir, sys_dirent, sys_next) \ - while (!readdir_r(sys_dir, &sys_dirent, &sys_next) && sys_next) \ - if (sys_dirent.d_type == DT_DIR && \ - (strcmp(sys_dirent.d_name, ".")) && \ - (strcmp(sys_dirent.d_name, ".."))) +#define for_each_subsystem (sys_dir, sys_dirent) \ + while ((sys_dirent = readdir(sys_dir)) != NULL) \ + if (sys_dirent->d_type == DT_DIR && \ + (strcmp(sys_dirent->d_name, ".")) && \ + (strcmp(sys_dirent->d_name, "..")))static int tp_event_has_id (struct dirent *sys_dir,struct dirent *evt_dir) {
@@ -144,12 +144,12 @@ static int tp_event_has_id(struct direntreturn 0 ; } -#define for_each_event (sys_dirent, evt_dir, evt_dirent, evt_next) \ - while (!readdir_r(evt_dir, &evt_dirent, &evt_next) && evt_next) \ - if (evt_dirent.d_type == DT_DIR && \ - (strcmp(evt_dirent.d_name, ".")) && \ - (strcmp(evt_dirent.d_name, "..")) && \ - (!tp_event_has_id(&sys_dirent, &evt_dirent))) +#define for_each_event (sys_dirent, evt_dir, evt_dirent) \ + while ((evt_dirent = readdir(evt_dir)) != NULL) \ + if (evt_dirent->d_type == DT_DIR && \ + (strcmp(evt_dirent->d_name, ".")) && \ + (strcmp(evt_dirent->d_name, "..")) && \ + (!tp_event_has_id(sys_dirent, evt_dirent)))#define MAX_EVENT_LENGTH 512
@@ -158,7 +158,7 @@ struct tracepoint_path *tracepoint_id_to {struct tracepoint_path *path =NULL ;DIR *sys_dir, *evt_dir; -struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; +struct dirent *sys_dirent, *evt_dirent;char id_buf[24 ];int fd;u64 id;
@@ -172,18 +172,18 @@ struct tracepoint_path *tracepoint_id_toif (!sys_dir)return NULL ; -for_each_subsystem (sys_dir, sys_dirent, sys_next) { +for_each_subsystem (sys_dir, sys_dirent) {snprintf (dir_path,MAXPATHLEN ,"%s/%s" , tracing_events_path, - sys_dirent.d_name); + sys_dirent->d_name); evt_dir =opendir (dir_path);if (!evt_dir)continue ; -for_each_event (sys_dirent, evt_dir, evt_dirent, evt_next) { +for_each_event (sys_dirent, evt_dir, evt_dirent) {snprintf (evt_path,MAXPATHLEN ,"%s/%s/id" , dir_path, - evt_dirent.d_name); + evt_dirent->d_name); fd =open (evt_path,O_RDONLY );if (fd <0 )continue ;
@@ -208,9 +208,9 @@ struct tracepoint_path *tracepoint_id_tofree (path);return NULL ; } -strncpy (path->system, sys_dirent.d_name, +strncpy (path->system, sys_dirent->d_name,MAX_EVENT_LENGTH ); -strncpy (path->name, evt_dirent.d_name, +strncpy (path->name, evt_dirent->d_name,MAX_EVENT_LENGTH );return path; }
@@ -1003,7 +1003,7 @@ void print_tracepoint_events(const char bool name_only) {DIR *sys_dir, *evt_dir; -struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; +struct dirent *sys_dirent, *evt_dirent;char evt_path[MAXPATHLEN ];char dir_path[MAXPATHLEN ];
@@ -1016,29 +1016,29 @@ void print_tracepoint_events(const charif (!sys_dir)return ; -for_each_subsystem (sys_dir, sys_dirent, sys_next) { +for_each_subsystem (sys_dir, sys_dirent) {if (subsys_glob !=NULL && - !strglobmatch (sys_dirent.d_name, subsys_glob)) + !strglobmatch (sys_dirent->d_name, subsys_glob))continue ;snprintf (dir_path,MAXPATHLEN ,"%s/%s" , tracing_events_path, - sys_dirent.d_name); + sys_dirent->d_name); evt_dir =opendir (dir_path);if (!evt_dir)continue ; -for_each_event (sys_dirent, evt_dir, evt_dirent, evt_next) { +for_each_event (sys_dirent, evt_dir, evt_dirent) {if (event_glob !=NULL && - !strglobmatch (evt_dirent.d_name, event_glob)) + !strglobmatch (evt_dirent->d_name, event_glob))continue ;if (name_only) { -printf ("%s:%s " , sys_dirent.d_name, evt_dirent.d_name); +printf ("%s:%s " , sys_dirent->d_name, evt_dirent->d_name);continue ; }snprintf (evt_path,MAXPATHLEN ,"%s:%s" , - sys_dirent.d_name, evt_dirent.d_name); + sys_dirent->d_name, evt_dirent->d_name);printf (" %-50s [%s]\n" , evt_path, event_type_descriptors[PERF_TYPE_TRACEPOINT ]); }
@@ -1054,7 +1054,7 @@ void print_tracepoint_events(const charint is_valid_tracepoint (const char *event_string) {DIR *sys_dir, *evt_dir; -struct dirent *sys_next, *evt_next, sys_dirent, evt_dirent; +struct dirent *sys_dirent, *evt_dirent;char evt_path[MAXPATHLEN ];char dir_path[MAXPATHLEN ];
@@ -1065,17 +1065,17 @@ int is_valid_tracepoint(const char *evenif (!sys_dir)return 0 ; -for_each_subsystem (sys_dir, sys_dirent, sys_next) { +for_each_subsystem (sys_dir, sys_dirent) {snprintf (dir_path,MAXPATHLEN ,"%s/%s" , tracing_events_path, - sys_dirent.d_name); + sys_dirent->d_name); evt_dir =opendir (dir_path);if (!evt_dir)continue ; -for_each_event (sys_dirent, evt_dir, evt_dirent, evt_next) { +for_each_event (sys_dirent, evt_dir, evt_dirent) {snprintf (evt_path,MAXPATHLEN ,"%s:%s" , - sys_dirent.d_name, evt_dirent.d_name); + sys_dirent->d_name, evt_dirent->d_name);if (!strcmp (evt_path, event_string)) {closedir (evt_dir);closedir (sys_dir);
PATCH 358/366 tools include: Add a __fallthrough statement
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Arnaldo Carvalho de Melo <[email protected]>
commit b5bf1733d6a391c4e90ea8f8468d83023be74a2a upstream.
For cases where implicit fall through case labels are intended, to let us inform that to gcc >= 7:
CC /tmp/build/perf/util/string.o
util/string.c: In function 'perf_atoll':
util/string.c:22:7: error: this statement may fall through [-Werror=implicit-fallthrough=]
if (*p)
^
util/string.c:24:3: note: here
case '\0':
^~~~So we introduce:
#define __fallthrough __attribute__ ((fallthrough))
And use it in such cases.
--- tools/include/linux/compiler.h | 9 +++++++++ 1 file changed, 9 insertions(+)
tools/include/linux/compiler.h +9 -0
@@ -37,4 +37,13 @@#define ACCESS_ONCE (x) (*(volatile typeof(x) *)&(x)) + +#ifndef __fallthrough +# if defined(__GNUC__) && __GNUC__ >=7 +# define __fallthrough __attribute__ ((fallthrough)) +# else +# define __fallthrough +# endif +#endif +#endif /* _TOOLS_LINUX_COMPILER_H */
PATCH 359/366 perf top: Use __fallthrough
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Arnaldo Carvalho de Melo <[email protected]>
commit 7b0214b702ad8e124e039a317beeebb3f020d125 upstream.
The implicit fall through case label here is intended, so let us inform that to gcc >= 7:
CC /tmp/build/perf/builtin-top.o
builtin-top.c: In function 'display_thread':
builtin-top.c:644:7: error: this statement may fall through [-Werror=implicit-fallthrough=]
if (errno == EINTR)
^ builtin-top.c:647:3: note: here
default:
^~~~~~~
--- tools/perf/builtin-top.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/builtin-top.c +1 -1
@@ -609,7 +609,7 @@ repeat:case -1 :if (errno ==EINTR )continue ; -/* Fall trhu */ + __fallthrough;default : c =getc (stdin);tcsetattr (0 ,TCSAFLUSH , &save);
PATCH 360/366 perf tools: Fix snprint warnings for gcc 8
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Jiri Olsa <[email protected]>
commit 77f18153c080855e1c3fb520ca31a4e61530121d upstream.
With gcc 8 we get new set of snprintf() warnings that breaks the compilation, one example:
tests/mem.c: In function ‘check’:
tests/mem.c:19:48: error: ‘%s’ directive output may be truncated writing \
up to 99 bytes into a region of size 89 [-Werror=format-truncation=]
snprintf(failure, sizeof failure, "unexpected %s", out);
The gcc docs says:
To avoid the warning either use a bigger buffer or handle the function's return value which indicates whether or not its output has been truncated.
Given that all these warnings are harmless, because the code either properly fails due to uncomplete file path or we don't care for truncated output at all, I'm changing all those snprintf() calls to scnprintf(), which actually 'checks' for the snprint return value so the gcc stays silent.
--- tools/perf/builtin-script.c | 22 +++++++++++----------- tools/perf/tests/attr.c | 4 ++-- tools/perf/tests/mem.c | 2 +- tools/perf/tests/pmu.c | 2 +- tools/perf/util/cgroup.c | 2 +- tools/perf/util/parse-events.c | 4 ++-- tools/perf/util/pmu.c | 2 +- 7 files changed, 19 insertions(+), 19 deletions(-)
tools/perf/builtin-script.c +11 -11
@@ -1235,8 +1235,8 @@ static int list_available_scripts(constreturn -1 ;for_each_lang (scripts_path, scripts_dir, lang_dirent) { -snprintf (lang_path,MAXPATHLEN ,"%s/%s/bin" , scripts_path, - lang_dirent->d_name); +scnprintf (lang_path,MAXPATHLEN ,"%s/%s/bin" , scripts_path, + lang_dirent->d_name); lang_dir =opendir (lang_path);if (!lang_dir)continue ;
@@ -1245,8 +1245,8 @@ static int list_available_scripts(const script_root =get_script_root (script_dirent,REPORT_SUFFIX );if (script_root) { desc =script_desc__findnew (script_root); -snprintf (script_path,MAXPATHLEN ,"%s/%s" , - lang_path, script_dirent->d_name); +scnprintf (script_path,MAXPATHLEN ,"%s/%s" , + lang_path, script_dirent->d_name);read_script_info (desc, script_path);free (script_root); }
@@ -1282,7 +1282,7 @@ static int check_ev_match(char *dir_nameint match, len;FILE *fp; -sprintf (filename,"%s/bin/%s-record" , dir_name, scriptname); +scnprintf (filename,MAXPATHLEN ,"%s/bin/%s-record" , dir_name, scriptname); fp =fopen (filename,"r" );if (!fp)
@@ -1358,8 +1358,8 @@ int find_scripts(char **scripts_array, c }for_each_lang (scripts_path, scripts_dir, lang_dirent) { -snprintf (lang_path,MAXPATHLEN ,"%s/%s" , scripts_path, - lang_dirent->d_name); +scnprintf (lang_path,MAXPATHLEN ,"%s/%s" , scripts_path, + lang_dirent->d_name);#ifdef NO_LIBPERL if (strstr (lang_path,"perl" ))continue ;
@@ -1414,8 +1414,8 @@ static char *get_script_path(const charreturn NULL ;for_each_lang (scripts_path, scripts_dir, lang_dirent) { -snprintf (lang_path,MAXPATHLEN ,"%s/%s/bin" , scripts_path, - lang_dirent->d_name); +scnprintf (lang_path,MAXPATHLEN ,"%s/%s/bin" , scripts_path, + lang_dirent->d_name); lang_dir =opendir (lang_path);if (!lang_dir)continue ;
@@ -1426,8 +1426,8 @@ static char *get_script_path(const charfree (__script_root);closedir (lang_dir);closedir (scripts_dir); -snprintf (script_path,MAXPATHLEN ,"%s/%s" , - lang_path, script_dirent->d_name); +scnprintf (script_path,MAXPATHLEN ,"%s/%s" , + lang_path, script_dirent->d_name);return strdup (script_path); }free (__script_root);
tools/perf/tests/attr.c +2 -2
@@ -147,8 +147,8 @@ static int run_dir(const char *d, constif (verbose) vcnt++; -snprintf (cmd,3 *PATH_MAX ,PYTHON " %s/attr.py -d %s/attr/ -p %s %.*s" , - d, d, perf, vcnt, v); +scnprintf (cmd,3 *PATH_MAX ,PYTHON " %s/attr.py -d %s/attr/ -p %s %.*s" , + d, d, perf, vcnt, v);return system (cmd); }
tools/perf/tests/pmu.c +1 -1
@@ -95,7 +95,7 @@ static char *test_format_dir_get(void)struct test_format *format = &test_formats[i];FILE *file; -snprintf (name,PATH_MAX ,"%s/%s" , dir, format->name); +scnprintf (name,PATH_MAX ,"%s/%s" , dir, format->name); file =fopen (name,"w" );if (!file)
tools/perf/util/cgroup.c +1 -1
@@ -64,7 +64,7 @@ static int open_cgroup(char *name)if (cgroupfs_find_mountpoint (mnt,PATH_MAX +1 ))return -1 ; -snprintf (path,PATH_MAX ,"%s/%s" , mnt, name); +scnprintf (path,PATH_MAX ,"%s/%s" , mnt, name); fd =open (path,O_RDONLY );if (fd ==-1 )
tools/perf/util/parse-events.c +2 -2
@@ -182,8 +182,8 @@ struct tracepoint_path *tracepoint_id_tofor_each_event (sys_dirent, evt_dir, evt_dirent) { -snprintf (evt_path,MAXPATHLEN ,"%s/%s/id" , dir_path, - evt_dirent->d_name); +scnprintf (evt_path,MAXPATHLEN ,"%s/%s/id" , dir_path, + evt_dirent->d_name); fd =open (evt_path,O_RDONLY );if (fd <0 )continue ;
tools/perf/util/pmu.c +1 -1
@@ -240,7 +240,7 @@ static int pmu_aliases_parse(char *dir,if (len >6 && !strcmp (name + len -6 ,".scale" ))continue ; -snprintf (path,PATH_MAX ,"%s/%s" , dir, name); +scnprintf (path,PATH_MAX ,"%s/%s" , dir, name); file =fopen (path,"r" );if (!file) {
PATCH 361/366 perf trace: Fix up fd -> pathname resolution
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Arnaldo Carvalho de Melo <[email protected]>
commit cdcd1e6bd8a92f8353fc2f37003c6eae2d1e6903 upstream.
There was a brown paper bag bug in the patch that introduced a reference implementation on using 'perf probe' made wannabe tracepoints that broke fd -> pathname resolution, fix it:
[root@zoo ~]# perf probe 'vfs_getname=getname_flags:65 pathname=result->name:string' Added new event:
probe:vfs_getname (on getname_flags:65 with pathname=result->name:string)
You can now use it in all perf tools, such as:
perf record -e probe:vfs_getname -aR sleep 1
[root@zoo ~]
Before:
[acme@zoo linux]$ trace touch -e open,fstat /tmp/b
1.159 ( 0.007 ms): open(filename: 0x7fd73f2fe088, flags: CLOEXEC ) = 3
1.163 ( 0.002 ms): fstat(fd: 3, statbuf: 0x7fff1b25e610 ) = 0
1.192 ( 0.009 ms): open(filename: 0x7fd73f4fedb8, flags: CLOEXEC ) = 3
1.201 ( 0.002 ms): fstat(fd: 3, statbuf: 0x7fff1b25e660 ) = 0
1.501 ( 0.013 ms): open(filename: 0x7fd73f0a1610, flags: CLOEXEC ) = 3
1.505 ( 0.002 ms): fstat(fd: 3, statbuf: 0x7fd73f2ddb60 ) = 0
1.581 ( 0.011 ms): open(filename: 0x7fff1b2603da, flags: CREAT|NOCTTY|NONBLOCK|WRONLY, mode: 438) = 3[acme@zoo linux]$
After:
[acme@zoo linux]$ trace touch -e open,fstat,dup2,mmap,close /tmp/b
1.105 ( 0.004 ms): mmap(len: 4096, prot: READ|WRITE, flags: PRIVATE|ANONYMOUS, fd: -1 ) = 0x2fbf000
1.136 ( 0.008 ms): open(filename: 0x7f8902dbc088, flags: CLOEXEC ) = 3
1.140 ( 0.002 ms): fstat(fd: 3</etc/ld.so.cache>, statbuf: 0x7fff19889ef0 ) = 0
1.146 ( 0.004 ms): mmap(len: 86079, prot: READ, flags: PRIVATE, fd: 3</etc/ld.so.cache> ) = 0x2fa9000
1.149 ( 0.001 ms): close(fd: 3</etc/ld.so.cache> ) = 0
1.170 ( 0.010 ms): open(filename: 0x7f8902fbcdb8, flags: CLOEXEC ) = 3
1.178 ( 0.002 ms): fstat(fd: 3</lib64/libc.so.6>, statbuf: 0x7fff19889f40 ) = 0
1.188 ( 0.006 ms): mmap(len: 3924576, prot: EXEC|READ, flags: PRIVATE|DENYWRITE, fd: 3</lib64/libc.so.6>) = 0x29e2000
1.207 ( 0.007 ms): mmap(addr: 0x7f8902d96000, len: 24576, prot: READ|WRITE, flags: PRIVATE|DENYWRITE|FIXED, fd: 3</lib64/libc.so.6>, off: 1785856) = 0x2d96000
1.217 ( 0.004 ms): mmap(addr: 0x7f8902d9c000, len: 16992, prot: READ|WRITE, flags: PRIVATE|ANONYMOUS|FIXED, fd: -1) = 0x2d9c000
1.228 ( 0.002 ms): close(fd: 3</lib64/libc.so.6> ) = 0
1.243 ( 0.003 ms): mmap(len: 4096, prot: READ|WRITE, flags: PRIVATE|ANONYMOUS, fd: -1 ) = 0x2fa8000
1.250 ( 0.003 ms): mmap(len: 8192, prot: READ|WRITE, flags: PRIVATE|ANONYMOUS, fd: -1 ) = 0x2fa6000
1.452 ( 0.010 ms): open(filename: 0x7f8902b5f610, flags: CLOEXEC ) = 3
1.455 ( 0.002 ms): fstat(fd: 3</usr/lib/locale/locale-archive>, statbuf: 0x7f8902d9bb60 ) = 0
1.461 ( 0.004 ms): mmap(len: 106070960, prot: READ, flags: PRIVATE, fd: 3</usr/lib/locale/locale-archive>) = 0xfc4b9000
1.469 ( 0.002 ms): close(fd: 3</usr/lib/locale/locale-archive> ) = 0
1.528 ( 0.010 ms): open(filename: 0x7fff1988c3da, flags: CREAT|NOCTTY|NONBLOCK|WRONLY, mode: 438) = 3
1.532 ( 0.002 ms): dup2(oldfd: 3</tmp/b> ) = 0
1.535 ( 0.001 ms): close(fd: 3</tmp/b> ) = 0
1.544 ( 0.001 ms): close( ) = 0
1.555 ( 0.001 ms): close(fd: 1 ) = 0
1.558 ( 0.001 ms): close(fd: 2 ) = 0[acme@zoo linux]$
--- tools/perf/builtin-trace.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
tools/perf/builtin-trace.c +2 -2
@@ -1276,11 +1276,11 @@ static const char *thread__fd_path(strucif (fd <0 )return NULL ; -if ((fd > ttrace->paths.max || ttrace->paths.table[fd] ==NULL )) +if ((fd > ttrace->paths.max || ttrace->paths.table[fd] ==NULL )) {if (!trace->live)return NULL ; ++trace->stats.proc_getname; -if (thread__read_fd_path (thread, fd)) { +if (thread__read_fd_path (thread, fd))return NULL ; }
PATCH 362/366 tools/lib/subcmd/pager.c: do not alias select() params
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Sergey Senozhatsky <[email protected]>
commit ad343a98e74e85aa91d844310e797f96fee6983b upstream.
Use a separate fd set for select()-s exception fds param to fix the following gcc warning:
pager.c:36:12: error: passing argument 2 to restrict-qualified parameter aliases with argument 4 [-Werror=restrict]
select(1, &in, NULL, &in, NULL);
^~~ ~~~--- tools/perf/util/pager.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
tools/perf/util/pager.c +4 -1
@@ -16,10 +16,13 @@ static void pager_preexec(void)* have real input */ fd_set in; +fd_set exception;FD_ZERO (&in); +FD_ZERO (&exception);FD_SET (0 , &in); -select (1 , &in,NULL , &in,NULL ); +FD_SET (0 , &exception); +select (1 , &in,NULL , &exception,NULL );setenv ("LESS" ,"FRSX" ,0 ); }
PATCH 363/366 perf tools: Remove duplicate const qualifier
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Eric Engestrom <[email protected]>
commit 3b556bced46aa6b1873da7faa18eff235e896adc upstream.
--- tools/perf/util/thread.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/thread.c +1 -1
@@ -177,7 +177,7 @@ void thread__find_cpumode_addr_location( struct addr_location *al) {size_t i; -const u8 const cpumodes[] = { +const u8 cpumodes[] = {PERF_RECORD_MISC_USER ,PERF_RECORD_MISC_KERNEL ,PERF_RECORD_MISC_GUEST_USER ,
PATCH 364/366 perf trace: Do not process PERF_RECORD_LOST twice
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Arnaldo Carvalho de Melo <[email protected]>
commit 3ed5ca2efff70e9f589087c2013789572901112d upstream.
We catch this record to provide a visual indication that events are getting lost, then call the default method to allow extra logging shared with the other tools to take place.
This extra logging was done twice because we were continuing to the "default" clause where machine__process_event() will end up calling machine__process_lost_event() again, fix it.
--- tools/perf/builtin-trace.c | 1 + 1 file changed, 1 insertion(+)
tools/perf/builtin-trace.c +1 -0
@@ -1359,6 +1359,7 @@ static int trace__process_event(struct tcolor_fprintf (trace->output,PERF_COLOR_RED ,"LOST %" PRIu64" events!\n" , event->lost.lost); ret =machine__process_lost_event (machine, event, sample); +break ;default : ret =machine__process_event (machine, event, sample);break ;
PATCH 365/366 perf thread_map: Correctly size buffer used with dirent->dt_name
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Arnaldo Carvalho de Melo <[email protected]>
commit bdf23a9a190d7ecea092fd5c4aabb7d4bd0a9980 upstream.
The size of dirent->dt_name is NAME_MAX + 1, but the size for the 'path' buffer is hard coded at 256, which may truncate it because we also prepend "/proc/", so that all that into account and thank gcc 7 for this warning:
/git/linux/tools/perf/util/thread_map.c: In function 'thread_map__new_by_uid':
/git/linux/tools/perf/util/thread_map.c:119:39: error: '%s' directive output may be truncated writing up to 255 bytes into a region of size 250 [-Werror=format-truncation=]
snprintf(path, sizeof(path), "/proc/%s", dirent->d_name);
^~
In file included from /usr/include/stdio.h:939:0,
from /git/linux/tools/perf/util/thread_map.c:5:
/usr/include/bits/stdio2.h:64:10: note: '__builtin___snprintf_chk' output between 7 and 262 bytes into a destination of size 256
return __builtin___snprintf_chk (__s, __n, __USE_FORTIFY_LEVEL - 1,
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
__bos (__s), __fmt, __va_arg_pack ());
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~--- tools/perf/util/thread_map.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
tools/perf/util/thread_map.c +1 -1
@@ -63,7 +63,7 @@ struct thread_map *thread_map__new_by_ui {DIR *proc;int max_threads =32 , items, i; -char path[256 ]; +char path[NAME_MAX +1 +6 ];struct dirent *dirent, **namelist =NULL ;struct thread_map *threads =malloc (sizeof (*threads) + max_threads *sizeof (pid_t));
PATCH 366/366 perf tools: Fix python extension build for gcc 8
In reply to Ben Hutchings3.16.61-rc1 review patch. If anyone has any objections, please let me know.
------------------
From: Jiri Olsa <[email protected]>
commit b7a313d84e853049062011d78cb04b6decd12f5c upstream.
The gcc 8 compiler won't compile the python extension code with the following errors (one example):
python.c:830:15: error: cast between incompatible function types from \
‘PyObject * (*)(struct pyrf_evsel *, PyObject *, PyObject *)’ \
uct _object * (*)(struct pyrf_evsel *, struct _object *, struct _object *)’} to \
‘PyObject * (*)(PyObject *, PyObject *)’ {aka ‘struct _object * (*)(struct _objeuct \
_object *)’} [-Werror=cast-function-type]
.ml_meth = (PyCFunction)pyrf_evsel__open,The problem with the PyMethodDef::ml_meth callback is that its type is determined based on the PyMethodDef::ml_flags value, which we set as METH_VARARGS | METH_KEYWORDS.
That indicates that the callback is expecting an extra PyObject* arg, and is actually PyCFunctionWithKeywords type, but the base PyMethodDef::ml_meth type stays PyCFunction.
Previous gccs did not find this, gcc8 now does. Fixing this by silencing this warning for python.c build.
Commiter notes:
Do not do that for CC=clang, as it breaks the build in some clang versions, like the ones in fedora up to fedora27:
fedora:25:error: unknown warning option '-Wno-cast-function-type'; did you mean '-Wno-bad-function-cast'? [-Werror,-Wunknown-warning-option] fedora:26:error: unknown warning option '-Wno-cast-function-type'; did you mean '-Wno-bad-function-cast'? [-Werror,-Wunknown-warning-option] fedora:27:error: unknown warning option '-Wno-cast-function-type'; did you mean '-Wno-bad-function-cast'? [-Werror,-Wunknown-warning-option] #
those have:
clang version 3.9.1 (tags/RELEASE_391/final)
The one in rawhide accepts that:
clang version 6.0.0 (tags/RELEASE_600/final)
--- tools/perf/util/setup.py | 2 ++ 1 file changed, 2 insertions(+)
tools/perf/util/setup.py +1 -0
@@ -21,6 +21,7 @@ class install_lib(_install_lib): cflags = getenv('CFLAGS', '').split() # switch off several checks (need to be at the end of cflags list) cflags += ['-fno-strict-aliasing', '-Wno-write-strings', '-Wno-unused-parameter' ] +cflags += ['-Wno-cast-function-type' ] build_lib = getenv('PYTHON_EXTBUILD_LIB') build_tmp = getenv('PYTHON_EXTBUILD_TMP')
Quoted 8 lines · Ben Hutchings
This is the start of the stable review cycle for the 3.16.61 release. There are 366 patches in this series, which will be posted as responses to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri Nov 16 18:00:00 UTC 2018. Anything received after that time might be too late.
Build results:
total: 140 pass: 139 fail: 1 Failed builds: i386:tools/perf Qemu test results: total: 217 pass: 217 fail: 0
Details are available at https://kerneltests.org/builders/.
Guenter
Quoted 17 lines · Guenter Roeck
Quoted 8 lines · Ben Hutchings
This is the start of the stable review cycle for the 3.16.61 release. There are 366 patches in this series, which will be posted as responses to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri Nov 16 18:00:00 UTC 2018. Anything received after that time might be too late.
Build results:
total: 140 pass: 139 fail: 1 Failed builds: i386:tools/perf Qemu test results: total: 217 pass: 217 fail: 0
Quoted 3 lines
Details are available at https://kerneltests.org/builders/.
Guenter
Hello Ben,
could you please include the following patch which makes it possible to build arm with gcc8 a71ae0513c232c844009738af135a13e5d7e39c ARM: fix put_user() for gcc-8 this is the version which landed in 3.18
and also the following patch 430c3fdb11ec1f0af1eca28460c922b9c1eb2ac5 turn off -Wattribute-alias this also the version which landed in 3.18
Thx,
Hannes
Quoted 27 lines · Johannes Pointner
Quoted 19 lines · Guenter Roeck
Quoted 11 lines · Ben Hutchings
This is the start of the stable review cycle for the 3.16.61 release.
There are 366 patches in this series, which will be posted as responses
to this one. If anyone has any issues with these being applied, please
let me know.Responses should be made by Fri Nov 16 18:00:00 UTC 2018. Anything received after that time might be too late.
Build results:
total: 140 pass: 139 fail: 1 Failed builds: i386:tools/perf Qemu test results: total: 217 pass: 217 fail: 0Quoted 3 lines
Details are available at https://kerneltests.org/builders/.
Guenter
Hello Ben,
Quoted 7 lines
could you please include the following patch which makes it possible to build arm with gcc8
a71ae0513c232c844009738af135a13e5d7e39cARM: fixput_user()for gcc-8 this is the version which landed in 3.18
and also the following patch430c3fdb11ec1f0af1eca28460c922b9c1eb2ac5turn off -Wattribute-alias this also the version which landed in 3.18
I'm not sure how much point there is in using gcc 8 for Linux 3.16, but these look harmless enough so I've queued them up for the next update.
Ben.
Signature · 2 lines
Ben Hutchings Absolutum obsoletum. (If it works, it's out of date.) - Stafford Beer
Quoted 11 lines · Guenter Roeck
Quoted 8 lines · Ben Hutchings
This is the start of the stable review cycle for the 3.16.61 release. There are 366 patches in this series, which will be posted as responses to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri Nov 16 18:00:00 UTC 2018. Anything received after that time might be too late.
Build results:
total: 140 pass: 139 fail: 1
So perf now builds in your x86_64 environment but still fails on i386. I didn't try i386 but that's still surprising...
Quoted 6 lines
Failed builds:
i386:tools/perf Qemu test results: total: 217 pass: 217 fail: 0Details are available at https://kerneltests.org/builders/.
Thanks for checking.
Ben.
Signature · 3 lines
Ben Hutchings Time is nature's way of making sure that everything doesn't happen at once.