From 94dd16e64207cc43f1a7dd1b13604b85aa83e6fa Mon Sep 17 00:00:00 2001 From: George Kulakowski <kulakowski@google.com> Date: Thu, 29 Nov 2018 11:22:41 -0800 Subject: [PATCH] [devmgr] Use RAII for the devhost API biglock Test: clang lock annotation checking Change-Id: I4f708e1449db34f0694ce1635eecd8d272f460f6 --- system/core/devmgr/devhost/api.cpp | 76 ++++++++------------------ system/core/devmgr/devhost/core.cpp | 32 +++++------ system/core/devmgr/devhost/devhost.cpp | 8 ++- system/core/devmgr/devhost/lock.h | 20 +++++++ 4 files changed, 62 insertions(+), 74 deletions(-) diff --git a/system/core/devmgr/devhost/api.cpp b/system/core/devmgr/devhost/api.cpp index eb0c1606655..ef1717f662f 100644 --- a/system/core/devmgr/devhost/api.cpp +++ b/system/core/devmgr/devhost/api.cpp @@ -52,10 +52,9 @@ __EXPORT zx_status_t device_add_from_driver(zx_driver_t* drv, zx_device_t* paren return ZX_ERR_INVALID_ARGS; } - DM_LOCK(); + ApiAutoLock lock; r = devhost_device_create(drv, parent_ref, args->name, args->ctx, args->ops, &dev); if (r != ZX_OK) { - DM_UNLOCK(); return r; } if (args->proto_id) { @@ -96,35 +95,27 @@ __EXPORT zx_status_t device_add_from_driver(zx_driver_t* drv, zx_device_t* paren // device_remove(). __UNUSED auto ptr = dev.leak_ref(); - DM_UNLOCK(); return r; } __EXPORT zx_status_t device_remove(zx_device_t* dev) { - zx_status_t r; - DM_LOCK(); + ApiAutoLock lock; // This recovers the leaked reference that happened in // device_add_from_driver() above. auto dev_ref = fbl::internal::MakeRefPtrNoAdopt(dev); - r = devhost_device_remove(std::move(dev_ref)); - DM_UNLOCK(); - return r; + return devhost_device_remove(std::move(dev_ref)); } __EXPORT zx_status_t device_rebind(zx_device_t* dev) { - zx_status_t r; - DM_LOCK(); + ApiAutoLock lock; fbl::RefPtr<zx_device_t> dev_ref(dev); - r = devhost_device_rebind(dev_ref); - DM_UNLOCK(); - return r; + return devhost_device_rebind(dev_ref); } __EXPORT void device_make_visible(zx_device_t* dev) { - DM_LOCK(); + ApiAutoLock lock; fbl::RefPtr<zx_device_t> dev_ref(dev); devhost_make_visible(dev_ref); - DM_UNLOCK(); } @@ -193,76 +184,53 @@ __EXPORT zx_handle_t get_root_resource() { __EXPORT zx_status_t load_firmware(zx_device_t* dev, const char* path, zx_handle_t* fw, size_t* size) { - zx_status_t r; - DM_LOCK(); + ApiAutoLock lock; fbl::RefPtr<zx_device_t> dev_ref(dev); - r = devhost_load_firmware(dev_ref, path, fw, size); - DM_UNLOCK(); - return r; + return devhost_load_firmware(dev_ref, path, fw, size); } // Interface Used by DevHost RPC Layer zx_status_t device_bind(const fbl::RefPtr<zx_device_t>& dev, const char* drv_libname) { - zx_status_t r; - DM_LOCK(); - r = devhost_device_bind(dev, drv_libname); - DM_UNLOCK(); - return r; + ApiAutoLock lock; + return devhost_device_bind(dev, drv_libname); } zx_status_t device_unbind(const fbl::RefPtr<zx_device_t>& dev) { - DM_LOCK(); - zx_status_t r = devhost_device_unbind(dev); - DM_UNLOCK(); - return r; + ApiAutoLock lock; + return devhost_device_unbind(dev); } zx_status_t device_open_at(const fbl::RefPtr<zx_device_t>& dev, fbl::RefPtr<zx_device_t>* out, const char* path, uint32_t flags) { - zx_status_t r; - DM_LOCK(); - r = devhost_device_open_at(dev, out, path, flags); - DM_UNLOCK(); - return r; + ApiAutoLock lock; + return devhost_device_open_at(dev, out, path, flags); } // This function is intended to consume the reference produced by // device_open_at() zx_status_t device_close(fbl::RefPtr<zx_device_t> dev, uint32_t flags) { - zx_status_t r; - DM_LOCK(); - r = devhost_device_close(std::move(dev), flags); - DM_UNLOCK(); - return r; + ApiAutoLock lock; + return devhost_device_close(std::move(dev), flags); } __EXPORT zx_status_t device_get_metadata(zx_device_t* dev, uint32_t type, void* buf, size_t buflen, size_t* actual) { - zx_status_t r; - DM_LOCK(); + ApiAutoLock lock; auto dev_ref = fbl::WrapRefPtr(dev); - r = devhost_get_metadata(dev_ref, type, buf, buflen, actual); - DM_UNLOCK(); - return r; + return devhost_get_metadata(dev_ref, type, buf, buflen, actual); } __EXPORT zx_status_t device_add_metadata(zx_device_t* dev, uint32_t type, const void* data, size_t length) { - zx_status_t r; - DM_LOCK(); + ApiAutoLock lock; auto dev_ref = fbl::WrapRefPtr(dev); - r = devhost_add_metadata(dev_ref, type, data, length); - DM_UNLOCK(); - return r; + return devhost_add_metadata(dev_ref, type, data, length); } __EXPORT zx_status_t device_publish_metadata(zx_device_t* dev, const char* path, uint32_t type, const void* data, size_t length) { - zx_status_t r; - DM_LOCK(); + ApiAutoLock lock; auto dev_ref = fbl::WrapRefPtr(dev); - r = devhost_publish_metadata(dev_ref, path, type, data, length); - DM_UNLOCK(); - return r; + return devhost_publish_metadata(dev_ref, path, type, data, length); } diff --git a/system/core/devmgr/devhost/core.cpp b/system/core/devmgr/devhost/core.cpp index f1fa82ed58a..36c841caed1 100644 --- a/system/core/devmgr/devhost/core.cpp +++ b/system/core/devmgr/devhost/core.cpp @@ -247,9 +247,8 @@ void devhost_finalize() { while ((dev = list.pop_front()) != nullptr) { // invoke release op if (dev->flags & DEV_FLAG_ADDED) { - DM_UNLOCK(); + ApiAutoRelock relock; dev->ReleaseOp(); - DM_LOCK(); } if (dev->parent) { @@ -557,9 +556,8 @@ zx_status_t devhost_device_unbind(const fbl::RefPtr<zx_device_t>& dev) REQ_DM_LO #if TRACE_ADD_REMOVE printf("call unbind dev: %p(%s)\n", dev.get(), dev->name); #endif - DM_UNLOCK(); + ApiAutoRelock relock; dev->UnbindOp(); - DM_LOCK(); } } return ZX_OK; @@ -575,14 +573,15 @@ zx_status_t devhost_device_open_at(const fbl::RefPtr<zx_device_t>& dev, } fbl::RefPtr<zx_device_t> new_ref(dev); zx_status_t r; - DM_UNLOCK(); zx_device_t* opened_dev = nullptr; - if (path) { - r = dev->OpenAtOp(&opened_dev, path, flags); - } else { - r = dev->OpenOp(&opened_dev, flags); + { + ApiAutoRelock relock; + if (path) { + r = dev->OpenAtOp(&opened_dev, path, flags); + } else { + r = dev->OpenOp(&opened_dev, flags); + } } - DM_LOCK(); if (r < 0) { new_ref.reset(); } else if (opened_dev != nullptr) { @@ -601,10 +600,8 @@ zx_status_t devhost_device_open_at(const fbl::RefPtr<zx_device_t>& dev, } zx_status_t devhost_device_close(fbl::RefPtr<zx_device_t> dev, uint32_t flags) REQ_DM_LOCK { - DM_UNLOCK(); - zx_status_t r = dev->CloseOp(flags); - DM_LOCK(); - return r; + ApiAutoRelock relock; + return dev->CloseOp(flags); } static zx_status_t devhost_device_suspend_locked(const fbl::RefPtr<zx_device>& dev, @@ -621,9 +618,10 @@ static zx_status_t devhost_device_suspend_locked(const fbl::RefPtr<zx_device>& d } // then invoke our suspend hook - DM_UNLOCK(); - st = dev->ops->suspend(dev->ctx, flags); - DM_LOCK(); + { + ApiAutoRelock relock; + st = dev->ops->suspend(dev->ctx, flags); + } // default_suspend() returns ZX_ERR_NOT_SUPPORTED if ((st != ZX_OK) && (st != ZX_ERR_NOT_SUPPORTED)) { diff --git a/system/core/devmgr/devhost/devhost.cpp b/system/core/devmgr/devhost/devhost.cpp index 40069821072..e61707f7c72 100644 --- a/system/core/devmgr/devhost/devhost.cpp +++ b/system/core/devmgr/devhost/devhost.cpp @@ -533,9 +533,11 @@ static zx_status_t fidl_Suspend(void* raw_ctx, uint32_t flags, fidl_txn_t* txn) while (device->parent != nullptr) { device = device->parent; } - DM_LOCK(); - zx_status_t r = devhost_device_suspend(device, flags); - DM_UNLOCK(); + zx_status_t r; + { + ApiAutoLock lock; + r = devhost_device_suspend(device, flags); + } // TODO(teisenbe): We should probably check this return... fuchsia_device_manager_ControllerSuspend_reply(txn, r); return ZX_OK; diff --git a/system/core/devmgr/devhost/lock.h b/system/core/devmgr/devhost/lock.h index c021ae89dbf..f81521d401a 100644 --- a/system/core/devmgr/devhost/lock.h +++ b/system/core/devmgr/devhost/lock.h @@ -34,4 +34,24 @@ static inline bool DM_LOCK_HELD() { return thrd_equal(internal::devhost_api_lock_owner.load(), thrd_current()); } +class ApiAutoLock { +public: + ApiAutoLock() TA_ACQ(&::devmgr::internal::devhost_api_lock) { + DM_LOCK(); + } + ~ApiAutoLock() TA_REL(&::devmgr::internal::devhost_api_lock) { + DM_UNLOCK(); + } +}; + +class ApiAutoRelock { +public: + ApiAutoRelock() TA_REL(&::devmgr::internal::devhost_api_lock) { + DM_UNLOCK(); + } + ~ApiAutoRelock() TA_ACQ(&::devmgr::internal::devhost_api_lock) { + DM_LOCK(); + } +}; + } // namespace devmgr -- GitLab