From patchwork Fri Oct 26 13:48:06 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicolas Saenz Julienne X-Patchwork-Id: 10657381 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id AB97E14BD for ; Fri, 26 Oct 2018 13:58:25 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 9B1B02BEB6 for ; Fri, 26 Oct 2018 13:58:25 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8BF0A2BFA1; Fri, 26 Oct 2018 13:58:25 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-2.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 6CD3D2BFA1 for ; Fri, 26 Oct 2018 13:58:24 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-Id:Date:Subject:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=u1E37p/TH74eHIyAwAdsuZ9Q27eWdCqN9EldC1Eyy7w=; b=g86MBDrGPovZsj wpRcX69uD40lCgNa6ok6As8Ivb+3dITUoVpqo9aqR/hpHjm8fC28cSeerI21PzRMFGVrBjLYJBjzz +yAsdeKgXqU6xk8iUgAiMmXZoegtBN9SlVUQzaWDbiFSEbLl/7ph3GAVcImF4t4lI6Vk6iPidldO/ hW43LSdu2BDvXjnRd91njOzSCs9MfnOq/vYXt9y9cxbNK2rlnvBfehi9A2cYJH+jO4kqpdukA9ZeV GC+/MFTklNmD971I73aKytyBLN2VIFIzw7pQIZk5K0NygajoAj+Rv4DEt2FN/p5I2+8JMjG9pcmgg bJePrOuPsUWcPkmcgLZg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.90_1 #2 (Red Hat Linux)) id 1gG2cr-0000aA-NJ; Fri, 26 Oct 2018 13:58:09 +0000 Received: from mx2.suse.de ([195.135.220.15] helo=mx1.suse.de) by bombadil.infradead.org with esmtps (Exim 4.90_1 #2 (Red Hat Linux)) id 1gG2Tu-0002Xz-Gz; Fri, 26 Oct 2018 13:49:41 +0000 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx1.suse.de (Postfix) with ESMTP id 73EE8B052; Fri, 26 Oct 2018 13:48:36 +0000 (UTC) From: Nicolas Saenz Julienne To: stefan.wahren@i2se.com, eric@anholt.net, dave.stevenson@raspberrypi.org Subject: [PATCH RFC 11/18] staging: vchiq_arm: use completions instead of semaphores Date: Fri, 26 Oct 2018 15:48:06 +0200 Message-Id: <20181026134813.7775-12-nsaenzjulienne@suse.de> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20181026134813.7775-1-nsaenzjulienne@suse.de> References: <20181026134813.7775-1-nsaenzjulienne@suse.de> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20181026_064854_977196_F49AA7BA X-CRM114-Status: GOOD ( 15.91 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devel@driverdev.osuosl.org, gregkh@linuxfoundation.org, linux-kernel@vger.kernel.org, nsaenzjulienne@suse.de, linux-rpi-kernel@lists.infradead.org, linux-arm-kernel@lists.infradead.org Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP It is preferred in the kernel to avoid using semaphores to wait for events, as they are optimised for the opposite situation; where the common case is that they are available and may block only occasionally. FYI see this thread: https://lkml.org/lkml/2008/4/11/323. Also completions are semantically more explicit in this case. Signed-off-by: Nicolas Saenz Julienne --- .../interface/vchiq_arm/vchiq_arm.c | 58 ++++++++++--------- 1 file changed, 31 insertions(+), 27 deletions(-) diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c index 1cdfdb714abc..463d0eec2e96 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c @@ -44,7 +44,7 @@ #include #include #include -#include +#include #include #include #include @@ -121,9 +121,9 @@ typedef struct user_service_struct { int message_available_pos; int msg_insert; int msg_remove; - struct semaphore insert_event; - struct semaphore remove_event; - struct semaphore close_event; + struct completion insert_event; + struct completion remove_event; + struct completion close_event; VCHIQ_HEADER_T * msg_queue[MSG_QUEUE_SIZE]; } USER_SERVICE_T; @@ -138,8 +138,8 @@ struct vchiq_instance_struct { VCHIQ_COMPLETION_DATA_T completions[MAX_COMPLETIONS]; int completion_insert; int completion_remove; - struct semaphore insert_event; - struct semaphore remove_event; + struct completion insert_event; + struct completion remove_event; struct mutex completion_mutex; int connected; @@ -562,7 +562,8 @@ add_completion(VCHIQ_INSTANCE_T instance, VCHIQ_REASON_T reason, vchiq_log_trace(vchiq_arm_log_level, "%s - completion queue full", __func__); DEBUG_COUNT(COMPLETION_QUEUE_FULL_COUNT); - if (down_interruptible(&instance->remove_event) != 0) { + if (wait_for_completion_interruptible( + &instance->remove_event)) { vchiq_log_info(vchiq_arm_log_level, "service_callback interrupted"); return VCHIQ_RETRY; @@ -600,7 +601,7 @@ add_completion(VCHIQ_INSTANCE_T instance, VCHIQ_REASON_T reason, insert++; instance->completion_insert = insert; - up(&instance->insert_event); + complete(&instance->insert_event); return VCHIQ_SUCCESS; } @@ -673,7 +674,8 @@ service_callback(VCHIQ_REASON_T reason, VCHIQ_HEADER_T *header, } DEBUG_TRACE(SERVICE_CALLBACK_LINE); - if (down_interruptible(&user_service->remove_event) + if (wait_for_completion_interruptible( + &user_service->remove_event) != 0) { vchiq_log_info(vchiq_arm_log_level, "%s interrupted", __func__); @@ -705,7 +707,7 @@ service_callback(VCHIQ_REASON_T reason, VCHIQ_HEADER_T *header, } spin_unlock(&msg_queue_spinlock); - up(&user_service->insert_event); + complete(&user_service->insert_event); header = NULL; } @@ -745,7 +747,7 @@ static void close_delivered(USER_SERVICE_T *user_service) unlock_service(user_service->service); /* Wake the user-thread blocked in close_ or remove_service */ - up(&user_service->close_event); + complete(&user_service->close_event); user_service->close_pending = 0; } @@ -867,7 +869,7 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg) if (status == VCHIQ_SUCCESS) { /* Wake the completion thread and ask it to exit */ instance->closing = 1; - up(&instance->insert_event); + complete(&instance->insert_event); } break; @@ -948,9 +950,9 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg) instance->completion_remove - 1; user_service->msg_insert = 0; user_service->msg_remove = 0; - sema_init(&user_service->insert_event, 0); - sema_init(&user_service->remove_event, 0); - sema_init(&user_service->close_event, 0); + init_completion(&user_service->insert_event); + init_completion(&user_service->remove_event); + init_completion(&user_service->close_event); if (args.is_open) { status = vchiq_open_service_internal @@ -1007,7 +1009,8 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg) has been closed until the client library calls the CLOSE_DELIVERED ioctl, signalling close_event. */ if (user_service->close_pending && - down_interruptible(&user_service->close_event)) + wait_for_completion_interruptible( + &user_service->close_event)) status = VCHIQ_RETRY; break; } @@ -1182,7 +1185,8 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg) DEBUG_TRACE(AWAIT_COMPLETION_LINE); mutex_unlock(&instance->completion_mutex); - rc = down_interruptible(&instance->insert_event); + rc = wait_for_completion_interruptible( + &instance->insert_event); mutex_lock(&instance->completion_mutex); if (rc != 0) { DEBUG_TRACE(AWAIT_COMPLETION_LINE); @@ -1310,7 +1314,7 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg) } if (ret != 0) - up(&instance->remove_event); + complete(&instance->remove_event); mutex_unlock(&instance->completion_mutex); DEBUG_TRACE(AWAIT_COMPLETION_LINE); } break; @@ -1350,8 +1354,8 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg) do { spin_unlock(&msg_queue_spinlock); DEBUG_TRACE(DEQUEUE_MESSAGE_LINE); - if (down_interruptible( - &user_service->insert_event) != 0) { + if (wait_for_completion_interruptible( + &user_service->insert_event)) { vchiq_log_info(vchiq_arm_log_level, "DEQUEUE_MESSAGE interrupted"); ret = -EINTR; @@ -1373,7 +1377,7 @@ vchiq_ioctl(struct file *file, unsigned int cmd, unsigned long arg) user_service->msg_remove++; spin_unlock(&msg_queue_spinlock); - up(&user_service->remove_event); + complete(&user_service->remove_event); if (header == NULL) ret = -ENOTCONN; else if (header->size <= args.bufsize) { @@ -1979,8 +1983,8 @@ vchiq_open(struct inode *inode, struct file *file) vchiq_debugfs_add_instance(instance); - sema_init(&instance->insert_event, 0); - sema_init(&instance->remove_event, 0); + init_completion(&instance->insert_event); + init_completion(&instance->remove_event); mutex_init(&instance->completion_mutex); mutex_init(&instance->bulk_waiter_list_mutex); INIT_LIST_HEAD(&instance->bulk_waiter_list); @@ -2033,12 +2037,12 @@ vchiq_release(struct inode *inode, struct file *file) /* Wake the completion thread and ask it to exit */ instance->closing = 1; - up(&instance->insert_event); + complete(&instance->insert_event); mutex_unlock(&instance->completion_mutex); /* Wake the slot handler if the completion queue is full. */ - up(&instance->remove_event); + complete(&instance->remove_event); /* Mark all services for termination... */ i = 0; @@ -2047,7 +2051,7 @@ vchiq_release(struct inode *inode, struct file *file) USER_SERVICE_T *user_service = service->base.userdata; /* Wake the slot handler if the msg queue is full. */ - up(&user_service->remove_event); + complete(&user_service->remove_event); vchiq_terminate_service_internal(service); unlock_service(service); @@ -2103,7 +2107,7 @@ vchiq_release(struct inode *inode, struct file *file) /* Wake any blocked user-thread */ if (instance->use_close_delivered) - up(&user_service->close_event); + complete(&user_service->close_event); unlock_service(service); } instance->completion_remove++;