mirror-linux/include/trace/events
David Howells 540b1c48c3 rxrpc: Fix deadlock between call creation and sendmsg/recvmsg
All the routines by which rxrpc is accessed from the outside are serialised
by means of the socket lock (sendmsg, recvmsg, bind,
rxrpc_kernel_begin_call(), ...) and this presents a problem:

 (1) If a number of calls on the same socket are in the process of
     connection to the same peer, a maximum of four concurrent live calls
     are permitted before further calls need to wait for a slot.

 (2) If a call is waiting for a slot, it is deep inside sendmsg() or
     rxrpc_kernel_begin_call() and the entry function is holding the socket
     lock.

 (3) sendmsg() and recvmsg() or the in-kernel equivalents are prevented
     from servicing the other calls as they need to take the socket lock to
     do so.

 (4) The socket is stuck until a call is aborted and makes its slot
     available to the waiter.

Fix this by:

 (1) Provide each call with a mutex ('user_mutex') that arbitrates access
     by the users of rxrpc separately for each specific call.

 (2) Make rxrpc_sendmsg() and rxrpc_recvmsg() unlock the socket as soon as
     they've got a call and taken its mutex.

     Note that I'm returning EWOULDBLOCK from recvmsg() if MSG_DONTWAIT is
     set but someone else has the lock.  Should I instead only return
     EWOULDBLOCK if there's nothing currently to be done on a socket, and
     sleep in this particular instance because there is something to be
     done, but we appear to be blocked by the interrupt handler doing its
     ping?

 (3) Make rxrpc_new_client_call() unlock the socket after allocating a new
     call, locking its user mutex and adding it to the socket's call tree.
     The call is returned locked so that sendmsg() can add data to it
     immediately.

     From the moment the call is in the socket tree, it is subject to
     access by sendmsg() and recvmsg() - even if it isn't connected yet.

 (4) Lock new service calls in the UDP data_ready handler (in
     rxrpc_new_incoming_call()) because they may already be in the socket's
     tree and the data_ready handler makes them live immediately if a user
     ID has already been preassigned.

     Note that the new call is locked before any notifications are sent
     that it is live, so doing mutex_trylock() *ought* to always succeed.
     Userspace is prevented from doing sendmsg() on calls that are in a
     too-early state in rxrpc_do_sendmsg().

 (5) Make rxrpc_new_incoming_call() return the call with the user mutex
     held so that a ping can be scheduled immediately under it.

     Note that it might be worth moving the ping call into
     rxrpc_new_incoming_call() and then we can drop the mutex there.

 (6) Make rxrpc_accept_call() take the lock on the call it is accepting and
     release the socket after adding the call to the socket's tree.  This
     is slightly tricky as we've dequeued the call by that point and have
     to requeue it.

     Note that requeuing emits a trace event.

 (7) Make rxrpc_kernel_send_data() and rxrpc_kernel_recv_data() take the
     new mutex immediately and don't bother with the socket mutex at all.

This patch has the nice bonus that calls on the same socket are now to some
extent parallelisable.

Note that we might want to move rxrpc_service_prealloc() calls out from the
socket lock and give it its own lock, so that we don't hang progress in
other calls because we're waiting for the allocator.

We probably also want to avoid calling rxrpc_notify_socket() from within
the socket lock (rxrpc_accept_call()).

Signed-off-by: David Howells <dhowells@redhat.com>
Tested-by: Marc Dionne <marc.c.dionne@auristor.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
2017-03-01 09:50:58 -08:00
..
9p.h
afs.h afs: Refcount the afs_call struct 2017-01-09 11:10:02 +00:00
alarmtimer.h ktime: Get rid of the union 2016-12-25 17:21:22 +01:00
asoc.h ASoC: trace: fix printing jack name 2016-02-26 10:52:48 +09:00
bcache.h block: better op and flags encoding 2016-10-28 08:48:16 -06:00
block.h block: cleanup tracing 2017-01-27 15:08:35 -07:00
bpf.h bpf: add initial bpf tracepoints 2017-01-25 13:17:47 -05:00
btrfs.h btrfs: Make btrfs_ino take a struct btrfs_inode 2017-02-14 15:50:51 +01:00
cgroup.h kernfs: handle null pointers while printing node name and path 2017-02-10 16:02:26 +01:00
clk.h
cma.h
compaction.h mm, trace: extract COMPACTION_STATUS and ZONE_TYPE to a common header 2017-02-22 16:41:27 -08:00
context_tracking.h
cpuhp.h cpu/hotplug: Add multi instance support 2016-09-02 20:05:05 +02:00
devlink.h devlink: fix trace format string 2016-07-14 22:16:05 -07:00
dma_fence.h dma-buf: Rename struct fence to dma_fence 2016-10-25 14:40:39 +02:00
ext4.h don't bother with ->d_inode->i_sb - it's always equal to ->d_sb 2016-04-10 17:11:51 -04:00
f2fs.h for-f2fs-4.10 2016-12-14 09:07:36 -08:00
fib.h
fib6.h ipv6, trace: fix tos reporting on fib6_table_lookup 2016-03-20 13:44:34 -04:00
filelock.h locks: sprinkle some tracepoints around the file locking code 2016-01-08 11:38:13 -05:00
filemap.h
fs_dax.h mm, dax: change pmd_fault() to take only vmf parameter 2017-02-22 16:41:26 -08:00
gpio.h
host1x.h
hswadsp.h
huge_memory.h mm, thp: convert from optimistic swapin collapsing to conservative 2016-07-26 16:19:19 -07:00
i2c.h tracing: Have the reg function allow to fail 2016-12-09 09:13:30 -05:00
intel-sst.h
intel_ish.h HID: intel-ish-hid: ipc layer 2016-08-17 11:13:07 +02:00
iommu.h
ipi.h
irq.h irq: Fix typo in tracepoint.xml 2016-09-29 10:03:38 +02:00
jbd2.h
kmem.h Nothing major this round. Mostly small clean ups and fixes. 2016-03-24 10:52:25 -07:00
kvm.h KVM: x86: add KVM_CAP_X2APIC_API 2016-07-14 09:03:57 +02:00
libata.h ata: Handle ATA NCQ NO-DATA commands correctly 2016-07-15 08:08:13 -04:00
lock.h
mce.h x86/mce/AMD: Save MCA_IPID in MCE struct on SMCA systems 2016-09-13 15:23:12 +02:00
mdio.h net/phy: add trace events for mdio accesses 2016-11-24 11:55:43 -05:00
migrate.h
mmc.h mmc: core: Provide tracepoints for request processing 2016-05-02 10:33:11 +02:00
mmflags.h mm, vmscan: show LRU name in mm_vmscan_lru_isolate tracepoint 2017-02-22 16:41:29 -08:00
module.h
napi.h net: fixup for tracepoint napi:napi_poll 2016-07-15 15:55:01 -07:00
net.h
nilfs2.h nilfs2: add tracepoints for analyzing reading and writing metadata files 2015-11-06 17:50:42 -08:00
nmi.h
oom.h oom, trace: add compaction retry tracepoint 2017-02-22 16:41:27 -08:00
page_isolation.h mm/page_isolation: fix tracepoint to mirror check function behavior 2016-04-01 17:03:37 -05:00
page_ref.h mm/page_ref: add tracepoint to track down page reference manipulation 2016-03-17 15:09:34 -07:00
pagemap.h
power.h cpufreq: intel_pstate: Add io_boost trace 2016-09-16 23:55:30 +02:00
power_cpu_migrate.h
printk.h printk, tracing: Avoiding unneeded blank lines 2016-07-15 15:52:41 -04:00
random.h
rcu.h rcu: Check cond_resched_rcu_qs() state less often to reduce GP overhead 2017-01-23 11:44:18 -08:00
regulator.h
rpm.h
rxrpc.h rxrpc: Fix deadlock between call creation and sendmsg/recvmsg 2017-03-01 09:50:58 -08:00
sched.h
scsi.h scsi-trace: define ZBC_IN and ZBC_OUT 2016-04-11 16:57:09 -04:00
signal.h
skb.h
sock.h
spi.h
spmi.h
sunrpc.h SUNRPC: Add tracepoints for dropped and deferred requests 2016-07-13 15:53:43 -04:00
sunvnet.h sunvnet: Add support for perf LDC event tracing 2016-02-07 14:13:05 -05:00
swiotlb.h swiotlb: Add swiotlb=noforce debug option 2016-12-19 09:05:20 -05:00
syscalls.h
target.h
task.h
thermal.h thermal: trace: migrating thermal traces to use TRACE_DEFINE_ENUM() macros 2016-03-15 07:51:40 +08:00
thermal_power_allocator.h
thp.h
timer.h This release has no new tracing features, just clean ups, minor fixes 2017-02-27 13:26:17 -08:00
tlb.h tracing: Remove duplicate checks for online CPUs 2016-03-08 11:19:28 -05:00
udp.h
ufs.h scsi: ufs: add trace event for ufs commands 2017-01-05 18:10:04 -05:00
v4l2.h [media] media: videobuf2: Move timestamp to vb2_buffer 2015-12-18 13:53:31 -02:00
vb2.h [media] media: videobuf2: Move timestamp to vb2_buffer 2015-12-18 13:53:31 -02:00
vmscan.h mm, vmscan: add mm_vmscan_inactive_list_is_low tracepoint 2017-02-22 16:41:29 -08:00
vsock_virtio_transport_common.h VSOCK: Introduce virtio_vsock_common.ko 2016-08-02 02:57:29 +03:00
wbt.h blk-wbt: add general throttling mechanism 2016-11-10 13:53:32 -07:00
workqueue.h
writeback.h mm: vmscan: kick flushers when we encounter dirty pages on the LRU 2017-02-24 17:46:54 -08:00
xdp.h bpf: add initial bpf tracepoints 2017-01-25 13:17:47 -05:00
xen.h