linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
To: bcm-kernel-feedback-list@broadcom.com,
	linux-rpi-kernel@lists.infradead.org,
	linux-arm-kernel@lists.infradead.org,
	Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
Cc: kernel-list@raspberrypi.com, laurent.pinchart@ideasonboard.com,
	gregkh@linuxfoundation.org, linux-kernel@vger.kernel.org,
	devel@driverdev.osuosl.org
Subject: [RFC 26/50] staging: vchiq: Move message queue into struct vchiq_service
Date: Wed, 27 May 2020 13:53:31 +0200	[thread overview]
Message-ID: <20200527115400.31391-27-nsaenzjulienne@suse.de> (raw)
In-Reply-To: <20200527115400.31391-1-nsaenzjulienne@suse.de>

This has historically been handled by vchi, but there is no reason why
this couldn't be handled directly in vchiq.

The patch tries to avoid altering any behavior, with the exception of
the msg_queue size, which is now fixed to VCHIQ_MAX_SLOTS (it was set to
VCHIQ_MAX_SLOTS / 2). This is done to match vchiq's user_service message
queue, which could be merged with this one in the future.

Signed-off-by: Nicolas Saenz Julienne <nsaenzjulienne@suse.de>
---
 drivers/staging/vc04_services/Makefile        |  1 -
 .../interface/vchiq_arm/vchiq_core.c          | 46 ++++++++++++
 .../interface/vchiq_arm/vchiq_core.h          |  6 ++
 .../interface/vchiq_arm/vchiq_if.h            |  2 +
 .../interface/vchiq_arm/vchiq_shim.c          | 24 ++----
 .../interface/vchiq_arm/vchiq_util.c          | 73 -------------------
 .../interface/vchiq_arm/vchiq_util.h          | 22 ------
 7 files changed, 61 insertions(+), 113 deletions(-)
 delete mode 100644 drivers/staging/vc04_services/interface/vchiq_arm/vchiq_util.c

diff --git a/drivers/staging/vc04_services/Makefile b/drivers/staging/vc04_services/Makefile
index 5fc3b65224a3..6a426572793b 100644
--- a/drivers/staging/vc04_services/Makefile
+++ b/drivers/staging/vc04_services/Makefile
@@ -7,7 +7,6 @@ vchiq-objs := \
    interface/vchiq_arm/vchiq_2835_arm.o \
    interface/vchiq_arm/vchiq_debugfs.o \
    interface/vchiq_arm/vchiq_shim.o \
-   interface/vchiq_arm/vchiq_util.o \
    interface/vchiq_arm/vchiq_connected.o \
 
 obj-$(CONFIG_SND_BCM2835)		+= bcm2835-audio/
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
index 46b09b7154f8..0e9680904e68 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.c
@@ -2265,6 +2265,47 @@ vchiq_init_state(struct vchiq_state *state, struct vchiq_slot_zero *slot_zero)
 	return VCHIQ_ERROR;
 }
 
+void vchiq_msg_queue_push(unsigned handle, struct vchiq_header *header)
+{
+	struct vchiq_service *service = find_service_by_handle(handle);
+	int pos;
+
+	while (service->msg_queue_write == service->msg_queue_read +
+		VCHIQ_MAX_SLOTS) {
+		if (wait_for_completion_interruptible(&service->msg_queue_pop))
+			flush_signals(current);
+	}
+
+	pos = service->msg_queue_write++ & (VCHIQ_MAX_SLOTS - 1);
+	service->msg_queue[pos] = header;
+
+	complete(&service->msg_queue_push);
+}
+EXPORT_SYMBOL(vchiq_msg_queue_push);
+
+struct vchiq_header *vchiq_msg_hold(unsigned handle)
+{
+	struct vchiq_service *service = find_service_by_handle(handle);
+	struct vchiq_header *header;
+	int pos;
+
+	if (service->msg_queue_write == service->msg_queue_read)
+		return NULL;
+
+	while (service->msg_queue_write == service->msg_queue_read) {
+		if (wait_for_completion_interruptible(&service->msg_queue_push))
+			flush_signals(current);
+	}
+
+	pos = service->msg_queue_read++ & (VCHIQ_MAX_SLOTS - 1);
+	header = service->msg_queue[pos];
+
+	complete(&service->msg_queue_pop);
+
+	return header;
+}
+EXPORT_SYMBOL(vchiq_msg_hold);
+
 static int vchiq_validate_params(const struct vchiq_service_params *params)
 {
 	if (!params->callback || !params->fourcc) {
@@ -2319,12 +2360,17 @@ vchiq_add_service_internal(struct vchiq_state *state,
 	service->state         = state;
 	service->instance      = instance;
 	service->service_use_count = 0;
+	service->msg_queue_read = 0;
+	service->msg_queue_write = 0;
 	init_bulk_queue(&service->bulk_tx);
 	init_bulk_queue(&service->bulk_rx);
 	init_completion(&service->remove_event);
 	init_completion(&service->bulk_remove_event);
+	init_completion(&service->msg_queue_pop);
+	init_completion(&service->msg_queue_push);
 	mutex_init(&service->bulk_mutex);
 	memset(&service->stats, 0, sizeof(service->stats));
+	memset(&service->msg_queue, 0, sizeof(service->msg_queue));
 
 	/* Although it is perfectly possible to use a spinlock
 	** to protect the creation of services, it is overkill as it
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h
index 1fe6cd8b86c0..b97b661bea1c 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_core.h
@@ -297,6 +297,12 @@ struct vchiq_service {
 		uint64_t bulk_tx_bytes;
 		uint64_t bulk_rx_bytes;
 	} stats;
+
+	int msg_queue_read;
+	int msg_queue_write;
+	struct completion msg_queue_pop;
+	struct completion msg_queue_push;
+	struct vchiq_header *msg_queue[VCHIQ_MAX_SLOTS];
 };
 
 /* The quota information is outside struct vchiq_service so that it can
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_if.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_if.h
index b62fd6d6f1ac..8fd51d885a18 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_if.h
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_if.h
@@ -136,5 +136,7 @@ extern enum vchiq_status vchiq_dump_phys_mem(unsigned int service,
 
 extern enum vchiq_status vchiq_get_peer_version(unsigned int handle,
       short *peer_version);
+extern void vchiq_msg_queue_push(unsigned handle, struct vchiq_header *header);
+extern struct vchiq_header *vchiq_msg_hold(unsigned handle);
 
 #endif /* VCHIQ_IF_H */
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_shim.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_shim.c
index dcf8776834b1..85d79d0033bf 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_shim.c
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_shim.c
@@ -13,8 +13,6 @@
 struct vchi_service {
 	unsigned int handle;
 
-	struct vchiu_queue queue;
-
 	vchi_callback callback;
 	void *callback_param;
 };
@@ -172,10 +170,9 @@ int32_t vchi_msg_hold(struct vchi_service *service, void **data,
 {
 	struct vchiq_header *header;
 
-	if (vchiu_queue_is_empty(&service->queue))
-		return -1;
-
-	header = vchiu_queue_pop(&service->queue);
+	header = vchiq_msg_hold(service->handle);
+	if (!header)
+		return -ENOENT;
 
 	*data = header->data;
 	*msg_size = header->size;
@@ -272,7 +269,7 @@ static enum vchiq_status shim_callback(enum vchiq_reason reason,
 		(struct vchi_service *)VCHIQ_GET_SERVICE_USERDATA(handle);
 
 	if (reason == VCHIQ_MESSAGE_AVAILABLE)
-		vchiu_queue_push(&service->queue, header);
+		vchiq_msg_queue_push(service->handle, header);
 
 	service->callback(service->callback_param, reason, bulk_user);
 
@@ -285,13 +282,8 @@ static struct vchi_service *service_alloc(struct vchiq_instance *instance,
 	struct vchi_service *service = kzalloc(sizeof(struct vchi_service), GFP_KERNEL);
 
 	if (service) {
-		if (!vchiu_queue_init(&service->queue, 64)) {
-			service->callback = setup->callback;
-			service->callback_param = setup->callback_param;
-		} else {
-			kfree(service);
-			service = NULL;
-		}
+		service->callback = setup->callback;
+		service->callback_param = setup->callback_param;
 	}
 
 	return service;
@@ -299,10 +291,8 @@ static struct vchi_service *service_alloc(struct vchiq_instance *instance,
 
 static void service_free(struct vchi_service *service)
 {
-	if (service) {
-		vchiu_queue_delete(&service->queue);
+	if (service)
 		kfree(service);
-	}
 }
 
 int32_t vchi_service_open(struct vchiq_instance *instance,
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_util.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_util.c
deleted file mode 100644
index c1c81f9ab9e6..000000000000
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_util.c
+++ /dev/null
@@ -1,73 +0,0 @@
-// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
-/* Copyright (c) 2010-2012 Broadcom. All rights reserved. */
-
-#include "vchiq_util.h"
-
-static inline int is_pow2(int i)
-{
-	return i && !(i & (i - 1));
-}
-
-int vchiu_queue_init(struct vchiu_queue *queue, int size)
-{
-	WARN_ON(!is_pow2(size));
-
-	queue->size = size;
-	queue->read = 0;
-	queue->write = 0;
-	queue->initialized = 1;
-
-	init_completion(&queue->pop);
-	init_completion(&queue->push);
-
-	queue->storage = kcalloc(size, sizeof(struct vchiq_header *),
-				 GFP_KERNEL);
-	if (!queue->storage) {
-		vchiu_queue_delete(queue);
-		return -ENOMEM;
-	}
-	return 0;
-}
-
-void vchiu_queue_delete(struct vchiu_queue *queue)
-{
-	kfree(queue->storage);
-}
-
-int vchiu_queue_is_empty(struct vchiu_queue *queue)
-{
-	return queue->read == queue->write;
-}
-
-void vchiu_queue_push(struct vchiu_queue *queue, struct vchiq_header *header)
-{
-	if (!queue->initialized)
-		return;
-
-	while (queue->write == queue->read + queue->size) {
-		if (wait_for_completion_interruptible(&queue->pop))
-			flush_signals(current);
-	}
-
-	queue->storage[queue->write & (queue->size - 1)] = header;
-	queue->write++;
-
-	complete(&queue->push);
-}
-
-struct vchiq_header *vchiu_queue_pop(struct vchiu_queue *queue)
-{
-	struct vchiq_header *header;
-
-	while (queue->write == queue->read) {
-		if (wait_for_completion_interruptible(&queue->push))
-			flush_signals(current);
-	}
-
-	header = queue->storage[queue->read & (queue->size - 1)];
-	queue->read++;
-
-	complete(&queue->pop);
-
-	return header;
-}
diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_util.h b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_util.h
index 1c90a8da1a92..dcf081079c39 100644
--- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_util.h
+++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_util.h
@@ -24,26 +24,4 @@
 
 #include "vchiq_if.h"
 
-struct vchiu_queue {
-	int size;
-	int read;
-	int write;
-	int initialized;
-
-	struct completion pop;
-	struct completion push;
-
-	struct vchiq_header **storage;
-};
-
-extern int  vchiu_queue_init(struct vchiu_queue *queue, int size);
-extern void vchiu_queue_delete(struct vchiu_queue *queue);
-
-extern int vchiu_queue_is_empty(struct vchiu_queue *queue);
-
-extern void vchiu_queue_push(struct vchiu_queue *queue,
-			     struct vchiq_header *header);
-
-extern struct vchiq_header *vchiu_queue_pop(struct vchiu_queue *queue);
-
 #endif
-- 
2.26.2


  parent reply	other threads:[~2020-05-27 11:56 UTC|newest]

Thread overview: 52+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-05-27 11:53 [RFC 00/50] staging: vchiq: Getting rid of the vchi/vchiq split Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 01/50] staging: vchi: Get rid of vchi_service_destroy() Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 02/50] staging: vchi: Get rid of vchi_queue_user_message() Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 03/50] staging: vchiq: Move copy callback handling into vchiq Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 04/50] staging: vchi: Merge vchi_msg_queue() into vchi_queue_kernel_message() Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 05/50] staging: vchi: Get rid of vchi_service_set_option() Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 06/50] staging: vchi: Get rid of vchiq_status_to_vchi() Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 07/50] staging: vchi: Get rid of not implemented function declarations Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 08/50] staging: vchi: Get rid of C++ guards Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 09/50] staging: vchiq: move vchiq_release_message() into vchiq Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 10/50] staging: vchiq: Get rid of VCHIQ_SERVICE_OPENEND callback reason Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 11/50] staging: vchi: Get rid of all useless callback reasons Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 12/50] staging: vchi: Get rid of vchi_msg_peek() Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 13/50] staging: vchi: Get rid of struct vchi_instance_handle Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 14/50] staging: vchi: Unify struct shim_service and struct vchi_service_handle Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 15/50] staging: vc04_services: bcm2835-audio: Use vchi_msg_hold() Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 16/50] staging: vchi: Get rid of vchi_msg_dequeue() Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 17/50] staging: vchi_common: Get rid of all unused definitions Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 18/50] staging: vc04_services: vc-sm-cma: Get rid of the multiple connections option Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 19/50] staging: vchi: Get rid of unnecessary defines Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 20/50] staging: vc04_services: Get rid of vchi_cfg.h Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 21/50] staging: vchi: Get rid of flags argument in vchi_msg_hold() Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 22/50] staging: vchi: Use enum vchiq_bulk_mode instead of vchi's transmission flags Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 23/50] staging: vchi: Use vchiq's enum vchiq_reason Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 24/50] staging: vchi: Get rid of effect less expression Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 25/50] staging: vchiq: Introduce vchiq_validate_params() Nicolas Saenz Julienne
2020-05-27 11:53 ` Nicolas Saenz Julienne [this message]
2020-05-27 11:53 ` [RFC 27/50] staging: vchiq: Get rid of vchiq_util.h Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 28/50] staging: vchi: Expose struct vchi_service Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 29/50] staging: vchiq: Export vchiq_get_service_userdata() Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 30/50] staging: vchiq: Export vchiq_msg_queue_push Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 31/50] staging: vchi: Get rid of vchiq_shim's message callback Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 32/50] staging: vchiq: Don't use a typedef for vchiq_callback Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 33/50] staging: vchi: Use struct vchiq_service_params Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 34/50] staging: vchi: Get rid of struct vchi_service Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 35/50] staging: vchiq: Pass vchiq's message when holding a message Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 36/50] staging: vchi: Rework vchi_msg_hold() to match vchiq_msg_hold() Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 37/50] staging: vchiq: Unify fourcc definition mechanisms Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 38/50] staging: vchi: Get rid of struct vchiq_instance forward declaration Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 39/50] staging: vchi: Don't include vchiq_core.h Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 40/50] staging: vchiq: Get rid of unnecessary definitions in vchiq_if.h Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 41/50] staging: vchiq: Make vchiq_add_service() local Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 42/50] staging: vchiq: Move definitions only used by core into core header Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 43/50] staging: vchi: Get rid of vchi_bulk_queue_receive() Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 44/50] staging: vchi: Get rid of vchi_bulk_queue_transmit() Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 45/50] staging: vchi: Move vchi_queue_kernel_message() into vchiq Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 46/50] staging: vchiq: Get rid of vchi Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 47/50] staging: vchiq: Move conditional barrier definition into vchiq_core.h Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 48/50] staging: vchiq: Use vchiq.h as the main header file for services Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 49/50] staging: vchiq: Move defines into core header Nicolas Saenz Julienne
2020-05-27 11:53 ` [RFC 50/50] staging: vchiq: Move vchiq.h into include directory Nicolas Saenz Julienne
2020-05-27 12:08 ` [RFC 00/50] staging: vchiq: Getting rid of the vchi/vchiq split Greg KH

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200527115400.31391-27-nsaenzjulienne@suse.de \
    --to=nsaenzjulienne@suse.de \
    --cc=bcm-kernel-feedback-list@broadcom.com \
    --cc=devel@driverdev.osuosl.org \
    --cc=gregkh@linuxfoundation.org \
    --cc=kernel-list@raspberrypi.com \
    --cc=laurent.pinchart@ideasonboard.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-rpi-kernel@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).