summaryrefslogtreecommitdiff
path: root/CREDITS
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@gmail.com>2015-04-18 12:39:51 +0200
committerDavid Herrmann <dh.herrmann@gmail.com>2015-04-18 12:39:51 +0200
commit61875e1abd38a965c9f7dfca28068dd0a871961c (patch)
tree3919ed234b07c62755133579631e877b9850e8af /CREDITS
parentf396c12ecfda1717e5f76d6b4ab11e4db232e60d (diff)
kdbus: reduce scope of handle locking
A kdbus handle is used to create objects in the kdbus hierarchy. During open(), we do not have enough information to know how to setup the object. Therefore, we provide setup ioctls, which allow user-space to pass in parameters and options how the to-be-created object should behave. Once setup is done, we allow user-space to use ioctls to operate on that newly created object. It is important to notice: 1) Only one setup ioctl can ever be called on a handle. You cannot call multiple, different setup ioctls on the same handle. 2) A setup ioctl can only be called once, if it succeeded. If it failed, it must not modify the handle in any way. If it succeeded, no further setup ioctl can be issued. 3) After a setup ioctl is done, the handle is constant and must not be modified in any way. So far, we used a write-lock around all setup ioctls, and a read-lock around everything else. The handle setup-indicator (the type field) can only be set under the write-lock. Whenever you access the handle under a read-lock, you must verify it was set before, otherwise, you must bail out as the handle was not initialized, yet. This has the downside that we need a read-lock on all operations on the handle. For performance reasons, we should avoid that. This patch turns the rwlock into a mutex and removes the read-side lock from all paths. It relies on the 3 behaviors described above. With this patch, the mutex is only taken around setup ioctls. Furthermore, the setup-indicator (the type field) is only ever set if the mutex is held. The mutex guarantees that multiple setup ioctls cannot race, and also, that only one setup ioctl will ever succeed. If a setup ioctl is called after setup was already finished, we do not touch the handle at all and immediately fail. Furthermore, all other operations (non-setup operations) can only be called once setup is done. Therefore, we must synchronize them with any racing setup, otherwise, they might access the handle which is currently modified by setup. We protect from this race by setting the setup-indicator (the type field) _last_, and issue a write-barrier before setting it. Once it is set, we never modify the handle ever again; it is constant from now on until file-release. Hence, on the read-side we simply read the type field and issue a read-barrier afterwards. _Iff_ the type field was not set, yet, we must not access the handle in any way, but bail out immediately. Setup was not done, yet. But if the type field was set, the read-barrier pairs with the write-barrier during setup. All member fields of the handle object are guaranteed to be accessible by us, as the type-field is always the last field that is written. With this in place, we reduce the locking-overhead of all non-setup ioctls to a read-barrier, instead of a read-side lock. And in combination with the follow-up that removes the active-refs from kdbus_handle_poll(), we're now lock-free in ->poll and ->mmap callbacks. Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
Diffstat (limited to 'CREDITS')
0 files changed, 0 insertions, 0 deletions