Received: by 10.223.164.197 with SMTP id h5csp616710wrb; Sat, 4 Nov 2017 20:28:36 -0700 (PDT) X-Google-Smtp-Source: ABhQp+Sfp78kYafTYbQ82xuV+CAu/RYi+427z6qxEw+C/5rObs/bo09786g/QYl8WvbOHw56WePS X-Received: by 10.84.179.165 with SMTP id b34mr2212462plc.17.1509852516624; Sat, 04 Nov 2017 20:28:36 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1509852516; cv=none; d=google.com; s=arc-20160816; b=hCxbCpEsvvQfguY+repEnEG8XaYg5xUzPwY9fQL0sNg28UiBfJWx/6xWEByiot1U7H BlGluTW42/TgoT1/cIBhCF3LApTcsMT7b93zLUk23l6UYQmG0Cbim0n9/PmNx5eWoDTw BYxivk+/jGfxuI7gBqJNiLyj9NwjJFE60062q/lhztJjpW7cpfl8RNccTPXR8STMukup BrLMNAxzLIlBtd/rYYXrMtRyw4r08H9efeYlcTzTBMPWLEqUPhfvKT1MX8Q4+JGBuA35 7BP6x2IXOV8rMK8ISxY2ih/v+Q17Gpg+6JaTT29qDudhrW+HR9fLebCvU3IWF5RC5W32 gvFA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:dkim-signature:arc-authentication-results; bh=8wLcg1dAqoQ1Hg90D4H6OiO5OTB6zafZtIo60uv8ogw=; b=HBvLsp48K8aJABOxsfeIGe16GY5YPHJ8fINqgmOVUZgSubK/nHDDiZkkYjV5dGpQp8 Kzf6l7bhS1/54bj72MmAvWeKnnTp7MIJDWvCMr0FdqpkQPpsTs2oVn8GDRworvIV2eNs ry2zmblJOsgoe3HfVS/MaEgpRGuMMHAfjCry+17xK4uCFotUd8Ip5jcdaRYl7fykF7uE usPGHeIyIJIYV9h3el48H7ewmkhdAJXqeSFAQg1ezPOqeprTxHUhfSjRA9hz0KYFrblR ib3ypjn6JftQAwys7UWS0YdN3ncpU0r0qU/n3FQ03ml0f++wAPfcde5ksJuEPl8KWPJb x/Yw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@nexus-software-ie.20150623.gappssmtp.com header.s=20150623 header.b=01YRqTHs; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id n11si7270698pls.746.2017.11.04.20.28.23; Sat, 04 Nov 2017 20:28:36 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@nexus-software-ie.20150623.gappssmtp.com header.s=20150623 header.b=01YRqTHs; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752590AbdKED1r (ORCPT + 94 others); Sat, 4 Nov 2017 23:27:47 -0400 Received: from mail-wm0-f66.google.com ([74.125.82.66]:47577 "EHLO mail-wm0-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751619AbdKED1n (ORCPT ); Sat, 4 Nov 2017 23:27:43 -0400 Received: by mail-wm0-f66.google.com with SMTP id r196so7850438wmf.2 for ; Sat, 04 Nov 2017 20:27:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nexus-software-ie.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=8wLcg1dAqoQ1Hg90D4H6OiO5OTB6zafZtIo60uv8ogw=; b=01YRqTHs4+732YhRykon984k7pmiopdmYVhSu8au+kSoEOSDFIPSjIKbZIAvdQ3aWl UgrY5GFs0GeY8DYm1EeCaOYPc2Ak6jPIz2SavU10PekEHoLJFEB9/e+IZfF3cG1IZzFo fwPAzhA3yhpIhbNn0AGhJJZ+tlrNn9icNLxxgdme0SQKqj11N1WJMRnKsz4FBZwSazSY gxqVJ1vJZK7KZFhKohO6K+3xW0O5qzk8+Hpy/OnSgtgffYcKRn7hIwjThIWrghxuY/Vq dcD/CcBr0JCSTpMiK8zOGWPqgtPnrxeRSa2SE6dGjoucTroly0rmAZGKnf1rya+KkYaa YJJw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=8wLcg1dAqoQ1Hg90D4H6OiO5OTB6zafZtIo60uv8ogw=; b=Xup/1Vu5OC5/8iqs1c9nv1bhK0ebQYosKJXhuAMW/AvKHC+/lAIOeKDe58tx9zfpe1 HrHtiB42L2eYoukLMjW3bqL2V0s8WUZJBF/5II7bJnxoT/L4ZBF6Ld/JvDSAIFBsdJT9 IPo/beC3fPCmnlAe0/kub5DFjd7RtkYlkHXI1kYm/c8Eifv0zkYC3rE4JZ9Xp/khh+hK Y1jIKI1cX7aFOxavqhKHOR7PIiNbtoBNlPvm9VeRHZdrppfyX5fq/+S/YC3e6jNKFnfP VgfrYHFUi9l/CNP2UeEyd3yTH+Hg6rP5hEzLD1k7ZCIgOVZiiPe+X/nFqbOSqJAZrn6e +weg== X-Gm-Message-State: AMCzsaU3G2UF6XbUWBoj8B/+9kjoFZBfnjGU9P900H94KJl8KOoblfU7 b4iL8+1QxVSXAbk3eMtCo5hWuw== X-Received: by 10.80.140.153 with SMTP id q25mr15580887edq.147.1509852462433; Sat, 04 Nov 2017 20:27:42 -0700 (PDT) Received: from localhost.localdomain ([109.255.42.2]) by smtp.gmail.com with ESMTPSA id a1sm8075536edb.37.2017.11.04.20.27.41 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Sat, 04 Nov 2017 20:27:41 -0700 (PDT) From: Bryan O'Donoghue To: johan@kernel.org, elder@kernel.org, gregkh@linuxfoundation.org, devel@driverdev.osuosl.org, keescook@chromium.org, linux-kernel@vger.kernel.org Cc: Bryan O'Donoghue , greybus-dev@lists.linaro.org Subject: [PATCH 2/2] staging: greybus: loopback: convert loopback to use generic async operations Date: Sun, 5 Nov 2017 03:27:39 +0000 Message-Id: <1509852459-5847-3-git-send-email-pure.logic@nexus-software.ie> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1509852459-5847-1-git-send-email-pure.logic@nexus-software.ie> References: <1509852459-5847-1-git-send-email-pure.logic@nexus-software.ie> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Loopback has its own internal method for tracking and timing out asynchronous operations however previous patches make it possible to use functionality provided by operation.c to do this instead. Using the code in operation.c means we can completely subtract the timer, the work-queue, the kref and the cringe-worthy 'pending' flag. The completion callback triggered by operation.c will provide an authoritative result code - including -ETIMEDOUT for asynchronous operations. Signed-off-by: Bryan O'Donoghue Cc: Johan Hovold Cc: Alex Elder Cc: Greg Kroah-Hartman Cc: Kees Cook Cc: greybus-dev@lists.linaro.org Cc: devel@driverdev.osuosl.org Cc: linux-kernel@vger.kernel.org --- drivers/staging/greybus/loopback.c | 165 +++++++------------------------------ 1 file changed, 31 insertions(+), 134 deletions(-) diff --git a/drivers/staging/greybus/loopback.c b/drivers/staging/greybus/loopback.c index 3d92638..48599ed 100644 --- a/drivers/staging/greybus/loopback.c +++ b/drivers/staging/greybus/loopback.c @@ -59,11 +59,6 @@ struct gb_loopback_async_operation { struct gb_loopback *gb; struct gb_operation *operation; ktime_t ts; - struct timer_list timer; - struct list_head entry; - struct work_struct work; - struct kref kref; - bool pending; int (*completion)(struct gb_loopback_async_operation *op_async); }; @@ -427,56 +422,6 @@ static int gb_loopback_operation_sync(struct gb_loopback *gb, int type, return ret; } -static void __gb_loopback_async_operation_destroy(struct kref *kref) -{ - struct gb_loopback_async_operation *op_async; - - op_async = container_of(kref, struct gb_loopback_async_operation, kref); - - list_del(&op_async->entry); - if (op_async->operation) - gb_operation_put(op_async->operation); - atomic_dec(&op_async->gb->outstanding_operations); - wake_up(&op_async->gb->wq_completion); - kfree(op_async); -} - -static void gb_loopback_async_operation_get(struct gb_loopback_async_operation - *op_async) -{ - kref_get(&op_async->kref); -} - -static void gb_loopback_async_operation_put(struct gb_loopback_async_operation - *op_async) -{ - unsigned long flags; - - spin_lock_irqsave(&gb_dev.lock, flags); - kref_put(&op_async->kref, __gb_loopback_async_operation_destroy); - spin_unlock_irqrestore(&gb_dev.lock, flags); -} - -static struct gb_loopback_async_operation * - gb_loopback_operation_find(u16 id) -{ - struct gb_loopback_async_operation *op_async; - bool found = false; - unsigned long flags; - - spin_lock_irqsave(&gb_dev.lock, flags); - list_for_each_entry(op_async, &gb_dev.list_op_async, entry) { - if (op_async->operation->id == id) { - gb_loopback_async_operation_get(op_async); - found = true; - break; - } - } - spin_unlock_irqrestore(&gb_dev.lock, flags); - - return found ? op_async : NULL; -} - static void gb_loopback_async_wait_all(struct gb_loopback *gb) { wait_event(gb->wq_completion, @@ -488,83 +433,41 @@ static void gb_loopback_async_operation_callback(struct gb_operation *operation) struct gb_loopback_async_operation *op_async; struct gb_loopback *gb; ktime_t te; - bool err = false; + int result; te = ktime_get(); - op_async = gb_loopback_operation_find(operation->id); - if (!op_async) - return; - + result = gb_operation_result(operation); + op_async = gb_operation_get_data(operation); gb = op_async->gb; + mutex_lock(&gb->mutex); - if (!op_async->pending || gb_operation_result(operation)) { - err = true; - } else { - if (op_async->completion) - if (op_async->completion(op_async)) - err = true; - } + if (!result && op_async->completion) + result = op_async->completion(op_async); - if (!err) + if (!result) { gb->elapsed_nsecs = gb_loopback_calc_latency(op_async->ts, te); - - if (op_async->pending) { - if (err) - gb->error++; - gb->iteration_count++; - op_async->pending = false; - del_timer_sync(&op_async->timer); - gb_loopback_async_operation_put(op_async); - gb_loopback_calculate_stats(gb, err); + } else { + gb->error++; + if (result == -ETIMEDOUT) + gb->requests_timedout++; } - mutex_unlock(&gb->mutex); - - dev_dbg(&gb->connection->bundle->dev, "complete operation %d\n", - operation->id); - - gb_loopback_async_operation_put(op_async); -} - -static void gb_loopback_async_operation_work(struct work_struct *work) -{ - struct gb_loopback *gb; - struct gb_operation *operation; - struct gb_loopback_async_operation *op_async; - op_async = container_of(work, struct gb_loopback_async_operation, work); - gb = op_async->gb; - operation = op_async->operation; + gb->iteration_count++; + gb_loopback_calculate_stats(gb, result); - mutex_lock(&gb->mutex); - if (op_async->pending) { - gb->requests_timedout++; - gb->error++; - gb->iteration_count++; - op_async->pending = false; - gb_loopback_async_operation_put(op_async); - gb_loopback_calculate_stats(gb, true); - } mutex_unlock(&gb->mutex); - dev_dbg(&gb->connection->bundle->dev, "timeout operation %d\n", + dev_dbg(&gb->connection->bundle->dev, "complete operation %d\n", operation->id); - gb_operation_cancel(operation, -ETIMEDOUT); - gb_loopback_async_operation_put(op_async); -} - -static void gb_loopback_async_operation_timeout(unsigned long data) -{ - struct gb_loopback_async_operation *op_async; - u16 id = data; + /* Wake up waiters */ + atomic_dec(&op_async->gb->outstanding_operations); + wake_up(&gb->wq_completion); - op_async = gb_loopback_operation_find(id); - if (!op_async) { - pr_err("operation %d not found - time out ?\n", id); - return; - } - schedule_work(&op_async->work); + /* Release resources */ + gb_operation_put(operation); + kfree(op_async); } static int gb_loopback_async_operation(struct gb_loopback *gb, int type, @@ -575,15 +478,11 @@ static int gb_loopback_async_operation(struct gb_loopback *gb, int type, struct gb_loopback_async_operation *op_async; struct gb_operation *operation; int ret; - unsigned long flags; op_async = kzalloc(sizeof(*op_async), GFP_KERNEL); if (!op_async) return -ENOMEM; - INIT_WORK(&op_async->work, gb_loopback_async_operation_work); - kref_init(&op_async->kref); - operation = gb_operation_create(gb->connection, type, request_size, response_size, GFP_KERNEL); if (!operation) { @@ -594,33 +493,29 @@ static int gb_loopback_async_operation(struct gb_loopback *gb, int type, if (request_size) memcpy(operation->request->payload, request, request_size); + gb_operation_set_data(operation, op_async); + op_async->gb = gb; op_async->operation = operation; op_async->completion = completion; - spin_lock_irqsave(&gb_dev.lock, flags); - list_add_tail(&op_async->entry, &gb_dev.list_op_async); - spin_unlock_irqrestore(&gb_dev.lock, flags); - op_async->ts = ktime_get(); - op_async->pending = true; + atomic_inc(&gb->outstanding_operations); + mutex_lock(&gb->mutex); ret = gb_operation_request_send(operation, gb_loopback_async_operation_callback, - 0, + jiffies_to_msecs(gb->jiffy_timeout), GFP_KERNEL); if (ret) goto error; - setup_timer(&op_async->timer, gb_loopback_async_operation_timeout, - (unsigned long)operation->id); - op_async->timer.expires = jiffies + gb->jiffy_timeout; - add_timer(&op_async->timer); - goto done; error: - gb_loopback_async_operation_put(op_async); + atomic_dec(&gb->outstanding_operations); + gb_operation_put(operation); + kfree(op_async); done: mutex_unlock(&gb->mutex); return ret; @@ -1024,8 +919,10 @@ static int gb_loopback_fn(void *data) else if (type == GB_LOOPBACK_TYPE_SINK) error = gb_loopback_async_sink(gb, size); - if (error) + if (error) { gb->error++; + gb->iteration_count++; + } } else { /* We are effectively single threaded here */ if (type == GB_LOOPBACK_TYPE_PING) -- 2.7.4 From 1583351891541292907@xxx Mon Nov 06 21:00:32 +0000 2017 X-GM-THRID: 1583351891541292907 X-Gmail-Labels: Inbox,Category Forums,HistoricalUnread