The Linux Kernel Mailing List
 help / color / mirror / Atom feed
From: Martin Schwidefsky <schwidefsky@de.ibm.com>
To: linux-kernel@vger.kernel.org, linux-s390@vger.kernel.org
Cc: Heiko Carstens <heiko.carstens@de.ibm.com>,
	Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
Subject: [patch 20/60] iucv: Locking free version of iucv_message_(receive|send)
Date: Thu, 27 Nov 2008 11:30:40 +0100	[thread overview]
Message-ID: <20081127103133.367502008@de.ibm.com> (raw)
In-Reply-To: 20081127103020.528516828@de.ibm.com

[-- Attachment #1: 119-iucv-lockfree.diff --]
[-- Type: text/plain, Size: 9726 bytes --]

From: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>

Provide a locking free version of iucv_message_receive and iucv_message_send
that do not call local_bh_enable in a spin_lock_(bh|irqsave)() context.

Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
---

 include/net/iucv/iucv.h |   45 ++++++++++++++
 net/iucv/iucv.c         |  152 ++++++++++++++++++++++++++++++++++++------------
 2 files changed, 161 insertions(+), 36 deletions(-)

Index: quilt-2.6/include/net/iucv/iucv.h
===================================================================
--- quilt-2.6.orig/include/net/iucv/iucv.h
+++ quilt-2.6/include/net/iucv/iucv.h
@@ -337,12 +337,35 @@ int iucv_message_purge(struct iucv_path 
  * established paths. This function will deal with RMDATA messages
  * embedded in struct iucv_message as well.
  *
+ * Locking:	local_bh_enable/local_bh_disable
+ *
  * Returns the result from the CP IUCV call.
  */
 int iucv_message_receive(struct iucv_path *path, struct iucv_message *msg,
 			 u8 flags, void *buffer, size_t size, size_t *residual);
 
 /**
+ * __iucv_message_receive
+ * @path: address of iucv path structure
+ * @msg: address of iucv msg structure
+ * @flags: flags that affect how the message is received (IUCV_IPBUFLST)
+ * @buffer: address of data buffer or address of struct iucv_array
+ * @size: length of data buffer
+ * @residual:
+ *
+ * This function receives messages that are being sent to you over
+ * established paths. This function will deal with RMDATA messages
+ * embedded in struct iucv_message as well.
+ *
+ * Locking:	no locking.
+ *
+ * Returns the result from the CP IUCV call.
+ */
+int __iucv_message_receive(struct iucv_path *path, struct iucv_message *msg,
+			   u8 flags, void *buffer, size_t size,
+			   size_t *residual);
+
+/**
  * iucv_message_reject
  * @path: address of iucv path structure
  * @msg: address of iucv msg structure
@@ -386,12 +409,34 @@ int iucv_message_reply(struct iucv_path 
  * transmitted is in a buffer and this is a one-way message and the
  * receiver will not reply to the message.
  *
+ * Locking:	local_bh_enable/local_bh_disable
+ *
  * Returns the result from the CP IUCV call.
  */
 int iucv_message_send(struct iucv_path *path, struct iucv_message *msg,
 		      u8 flags, u32 srccls, void *buffer, size_t size);
 
 /**
+ * __iucv_message_send
+ * @path: address of iucv path structure
+ * @msg: address of iucv msg structure
+ * @flags: how the message is sent (IUCV_IPRMDATA, IUCV_IPPRTY, IUCV_IPBUFLST)
+ * @srccls: source class of message
+ * @buffer: address of data buffer or address of struct iucv_array
+ * @size: length of send buffer
+ *
+ * This function transmits data to another application. Data to be
+ * transmitted is in a buffer and this is a one-way message and the
+ * receiver will not reply to the message.
+ *
+ * Locking:	no locking.
+ *
+ * Returns the result from the CP IUCV call.
+ */
+int __iucv_message_send(struct iucv_path *path, struct iucv_message *msg,
+			u8 flags, u32 srccls, void *buffer, size_t size);
+
+/**
  * iucv_message_send2way
  * @path: address of iucv path structure
  * @msg: address of iucv msg structure
Index: quilt-2.6/net/iucv/iucv.c
===================================================================
--- quilt-2.6.orig/net/iucv/iucv.c
+++ quilt-2.6/net/iucv/iucv.c
@@ -957,7 +957,52 @@ int iucv_message_purge(struct iucv_path 
 EXPORT_SYMBOL(iucv_message_purge);
 
 /**
- * iucv_message_receive
+ * iucv_message_receive_iprmdata
+ * @path: address of iucv path structure
+ * @msg: address of iucv msg structure
+ * @flags: how the message is received (IUCV_IPBUFLST)
+ * @buffer: address of data buffer or address of struct iucv_array
+ * @size: length of data buffer
+ * @residual:
+ *
+ * Internal function used by iucv_message_receive and __iucv_message_receive
+ * to receive RMDATA data stored in struct iucv_message.
+ */
+static int iucv_message_receive_iprmdata(struct iucv_path *path,
+					 struct iucv_message *msg,
+					 u8 flags, void *buffer,
+					 size_t size, size_t *residual)
+{
+	struct iucv_array *array;
+	u8 *rmmsg;
+	size_t copy;
+
+	/*
+	 * Message is 8 bytes long and has been stored to the
+	 * message descriptor itself.
+	 */
+	if (residual)
+		*residual = abs(size - 8);
+	rmmsg = msg->rmmsg;
+	if (flags & IUCV_IPBUFLST) {
+		/* Copy to struct iucv_array. */
+		size = (size < 8) ? size : 8;
+		for (array = buffer; size > 0; array++) {
+			copy = min_t(size_t, size, array->length);
+			memcpy((u8 *)(addr_t) array->address,
+				rmmsg, copy);
+			rmmsg += copy;
+			size -= copy;
+		}
+	} else {
+		/* Copy to direct buffer. */
+		memcpy(buffer, rmmsg, min_t(size_t, size, 8));
+	}
+	return 0;
+}
+
+/**
+ * __iucv_message_receive
  * @path: address of iucv path structure
  * @msg: address of iucv msg structure
  * @flags: how the message is received (IUCV_IPBUFLST)
@@ -969,44 +1014,19 @@ EXPORT_SYMBOL(iucv_message_purge);
  * established paths. This function will deal with RMDATA messages
  * embedded in struct iucv_message as well.
  *
+ * Locking:	no locking
+ *
  * Returns the result from the CP IUCV call.
  */
-int iucv_message_receive(struct iucv_path *path, struct iucv_message *msg,
-			 u8 flags, void *buffer, size_t size, size_t *residual)
+int __iucv_message_receive(struct iucv_path *path, struct iucv_message *msg,
+			   u8 flags, void *buffer, size_t size, size_t *residual)
 {
 	union iucv_param *parm;
-	struct iucv_array *array;
-	u8 *rmmsg;
-	size_t copy;
 	int rc;
 
-	if (msg->flags & IUCV_IPRMDATA) {
-		/*
-		 * Message is 8 bytes long and has been stored to the
-		 * message descriptor itself.
-		 */
-		rc = (size < 8) ? 5 : 0;
-		if (residual)
-			*residual = abs(size - 8);
-		rmmsg = msg->rmmsg;
-		if (flags & IUCV_IPBUFLST) {
-			/* Copy to struct iucv_array. */
-			size = (size < 8) ? size : 8;
-			for (array = buffer; size > 0; array++) {
-				copy = min_t(size_t, size, array->length);
-				memcpy((u8 *)(addr_t) array->address,
-				       rmmsg, copy);
-				rmmsg += copy;
-				size -= copy;
-			}
-		} else {
-			/* Copy to direct buffer. */
-			memcpy(buffer, rmmsg, min_t(size_t, size, 8));
-		}
-		return 0;
-	}
-
-	local_bh_disable();
+	if (msg->flags & IUCV_IPRMDATA)
+		return iucv_message_receive_iprmdata(path, msg, flags,
+						     buffer, size, residual);
 	parm = iucv_param[smp_processor_id()];
 	memset(parm, 0, sizeof(union iucv_param));
 	parm->db.ipbfadr1 = (u32)(addr_t) buffer;
@@ -1022,6 +1042,37 @@ int iucv_message_receive(struct iucv_pat
 		if (residual)
 			*residual = parm->db.ipbfln1f;
 	}
+	return rc;
+}
+EXPORT_SYMBOL(__iucv_message_receive);
+
+/**
+ * iucv_message_receive
+ * @path: address of iucv path structure
+ * @msg: address of iucv msg structure
+ * @flags: how the message is received (IUCV_IPBUFLST)
+ * @buffer: address of data buffer or address of struct iucv_array
+ * @size: length of data buffer
+ * @residual:
+ *
+ * This function receives messages that are being sent to you over
+ * established paths. This function will deal with RMDATA messages
+ * embedded in struct iucv_message as well.
+ *
+ * Locking:	local_bh_enable/local_bh_disable
+ *
+ * Returns the result from the CP IUCV call.
+ */
+int iucv_message_receive(struct iucv_path *path, struct iucv_message *msg,
+			 u8 flags, void *buffer, size_t size, size_t *residual)
+{
+	int rc;
+
+	if (msg->flags & IUCV_IPRMDATA)
+		return iucv_message_receive_iprmdata(path, msg, flags,
+						     buffer, size, residual);
+	local_bh_disable();
+	rc = __iucv_message_receive(path, msg, flags, buffer, size, residual);
 	local_bh_enable();
 	return rc;
 }
@@ -1101,7 +1152,7 @@ int iucv_message_reply(struct iucv_path 
 EXPORT_SYMBOL(iucv_message_reply);
 
 /**
- * iucv_message_send
+ * __iucv_message_send
  * @path: address of iucv path structure
  * @msg: address of iucv msg structure
  * @flags: how the message is sent (IUCV_IPRMDATA, IUCV_IPPRTY, IUCV_IPBUFLST)
@@ -1113,15 +1164,16 @@ EXPORT_SYMBOL(iucv_message_reply);
  * transmitted is in a buffer and this is a one-way message and the
  * receiver will not reply to the message.
  *
+ * Locking:	no locking
+ *
  * Returns the result from the CP IUCV call.
  */
-int iucv_message_send(struct iucv_path *path, struct iucv_message *msg,
+int __iucv_message_send(struct iucv_path *path, struct iucv_message *msg,
 		      u8 flags, u32 srccls, void *buffer, size_t size)
 {
 	union iucv_param *parm;
 	int rc;
 
-	local_bh_disable();
 	parm = iucv_param[smp_processor_id()];
 	memset(parm, 0, sizeof(union iucv_param));
 	if (flags & IUCV_IPRMDATA) {
@@ -1144,6 +1196,34 @@ int iucv_message_send(struct iucv_path *
 	rc = iucv_call_b2f0(IUCV_SEND, parm);
 	if (!rc)
 		msg->id = parm->db.ipmsgid;
+	return rc;
+}
+EXPORT_SYMBOL(__iucv_message_send);
+
+/**
+ * iucv_message_send
+ * @path: address of iucv path structure
+ * @msg: address of iucv msg structure
+ * @flags: how the message is sent (IUCV_IPRMDATA, IUCV_IPPRTY, IUCV_IPBUFLST)
+ * @srccls: source class of message
+ * @buffer: address of send buffer or address of struct iucv_array
+ * @size: length of send buffer
+ *
+ * This function transmits data to another application. Data to be
+ * transmitted is in a buffer and this is a one-way message and the
+ * receiver will not reply to the message.
+ *
+ * Locking:	local_bh_enable/local_bh_disable
+ *
+ * Returns the result from the CP IUCV call.
+ */
+int iucv_message_send(struct iucv_path *path, struct iucv_message *msg,
+		      u8 flags, u32 srccls, void *buffer, size_t size)
+{
+	int rc;
+
+	local_bh_disable();
+	rc = __iucv_message_send(path, msg, flags, srccls, buffer, size);
 	local_bh_enable();
 	return rc;
 }

-- 
blue skies,
   Martin.

"Reality continues to ruin my life." - Calvin.


  parent reply	other threads:[~2008-11-27 10:40 UTC|newest]

Thread overview: 61+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-11-27 10:30 [patch 00/60] s390 feature patches for 2.6.29 Martin Schwidefsky
2008-11-27 10:30 ` [patch 01/60] vmcp: remove BKL Martin Schwidefsky
2008-11-27 10:30 ` [patch 02/60] arch_setup_additional_pages arguments Martin Schwidefsky
2008-11-27 10:30 ` [patch 03/60] introduce vdso on s390 Martin Schwidefsky
2008-11-27 10:30 ` [patch 04/60] convert etr/stp to stop_machine interface Martin Schwidefsky
2008-11-27 10:30 ` [patch 05/60] serialize stp/etr work Martin Schwidefsky
2008-11-27 10:30 ` [patch 06/60] convert s390 to generic IPI infrastructure Martin Schwidefsky
2008-11-27 10:30 ` [patch 07/60] Move stfle to header file Martin Schwidefsky
2008-11-27 10:30 ` [patch 08/60] zcrypt: Use of Thin Interrupts Martin Schwidefsky
2008-11-27 10:30 ` [patch 09/60] ap: Minor code beautification Martin Schwidefsky
2008-11-27 10:30 ` [patch 10/60] qdio: fix qeth port count detection Martin Schwidefsky
2008-11-27 10:30 ` [patch 11/60] qdio: add eqbs/sqbs instruction counters Martin Schwidefsky
2008-11-27 10:30 ` [patch 12/60] qdio: fix compile warning under 31 bit Martin Schwidefsky
2008-11-27 10:30 ` [patch 13/60] qdio: rework debug feature logging Martin Schwidefsky
2008-11-27 10:30 ` [patch 14/60] qdio: improve error handling for unexpected buffer states Martin Schwidefsky
2008-11-27 10:30 ` [patch 15/60] qdio: improve inbound buffer acknowledgement Martin Schwidefsky
2008-11-27 10:30 ` [patch 16/60] service level interface Martin Schwidefsky
2008-11-27 10:30 ` [patch 17/60] zfcp: Report microcode level through " Martin Schwidefsky
2008-11-27 10:30 ` [patch 18/60] dasd: improve dasd statistics proc interface Martin Schwidefsky
2008-11-27 10:30 ` [patch 19/60] struct device - replace bus_id with dev_name(), dev_set_name() Martin Schwidefsky
2008-11-27 10:30 ` Martin Schwidefsky [this message]
2008-11-27 10:30 ` [patch 21/60] s390/hvc_console: z/VM IUCV hypervisor console support Martin Schwidefsky
2008-11-27 10:30 ` [patch 22/60] ftrace: function tracer backend for s390 Martin Schwidefsky
2008-11-27 10:30 ` [patch 23/60] __page_to_pfn warnings Martin Schwidefsky
2008-11-27 10:30 ` [patch 24/60] remove ptrace warning on 31 bit Martin Schwidefsky
2008-11-27 10:30 ` [patch 25/60] cio: get rid of compile warning Martin Schwidefsky
2008-11-27 10:30 ` [patch 26/60] mark disabled_wait as noreturn function Martin Schwidefsky
2008-11-27 10:30 ` [patch 27/60] remove warnings with functions ending in BUG Martin Schwidefsky
2008-11-27 10:30 ` [patch 28/60] sclp vt220: fix compile warning Martin Schwidefsky
2008-11-27 10:30 ` [patch 29/60] Add processor type march=z10 and a processor type safety check Martin Schwidefsky
2008-11-27 10:30 ` [patch 30/60] dasd: Use accessors instead of using driver_data directly Martin Schwidefsky
2008-11-27 10:30 ` [patch 31/60] cio: update sac values Martin Schwidefsky
2008-11-27 10:30 ` [patch 32/60] Remove initial kernel stack backchain initialization Martin Schwidefsky
2008-11-27 10:30 ` [patch 33/60] cio: move irritating comment Martin Schwidefsky
2008-11-27 10:30 ` [patch 34/60] add new machine types to setup_hwcaps Martin Schwidefsky
2008-11-27 10:30 ` [patch 35/60] convert xpram printks to pr_xxx macros Martin Schwidefsky
2008-11-27 10:30 ` [patch 36/60] convert vmcp " Martin Schwidefsky
2008-11-27 10:30 ` [patch 37/60] convert lcs printks to dev_xxx and " Martin Schwidefsky
2008-11-27 10:30 ` [patch 38/60] convert cpcmd printks to " Martin Schwidefsky
2008-11-27 10:30 ` [patch 39/60] convert vmur " Martin Schwidefsky
2008-11-27 10:31 ` [patch 40/60] convert cio " Martin Schwidefsky
2008-11-27 10:31 ` [patch 41/60] convert cpacf " Martin Schwidefsky
2008-11-27 10:31 ` [patch 42/60] convert time " Martin Schwidefsky
2008-11-27 10:31 ` [patch 43/60] convert hypfs " Martin Schwidefsky
2008-11-27 10:31 ` [patch 44/60] convert setup " Martin Schwidefsky
2008-11-27 10:31 ` [patch 45/60] convert appldata " Martin Schwidefsky
2008-11-27 10:31 ` [patch 46/60] convert monreader " Martin Schwidefsky
2008-11-27 10:31 ` [patch 47/60] convert s390 debug feature " Martin Schwidefsky
2008-11-27 10:31 ` [patch 48/60] convert monwriter " Martin Schwidefsky
2008-11-27 10:31 ` [patch 49/60] convert dcssblk and extmem printks messages " Martin Schwidefsky
2008-11-27 10:31 ` [patch 50/60] convert ap_bus printks " Martin Schwidefsky
2008-11-27 10:31 ` [patch 51/60] convert iucv printks to dev_xxx and " Martin Schwidefsky
2008-11-27 10:31 ` [patch 52/60] convert sclp printks to " Martin Schwidefsky
2008-11-27 10:31 ` [patch 53/60] convert qeth printks to dev_xxx and " Martin Schwidefsky
2008-11-27 10:31 ` [patch 54/60] convert cpu related printks to " Martin Schwidefsky
2008-11-27 10:31 ` [patch 55/60] convert zfcp dumper " Martin Schwidefsky
2008-11-27 10:31 ` [patch 56/60] convert vmlogrdr " Martin Schwidefsky
2008-11-27 10:31 ` [patch 57/60] convert zfcp " Martin Schwidefsky
2008-11-27 10:31 ` [patch 58/60] convert ctcm printks to dev_xxx and " Martin Schwidefsky
2008-11-27 10:31 ` [patch 59/60] provide documentation for hvc_iucv printk & kernel parameter Martin Schwidefsky
2008-11-27 10:31 ` [patch 60/60] tape message cleanup Martin Schwidefsky

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=20081127103133.367502008@de.ibm.com \
    --to=schwidefsky@de.ibm.com \
    --cc=brueckner@linux.vnet.ibm.com \
    --cc=heiko.carstens@de.ibm.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-s390@vger.kernel.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