summary refs log tree commit diff
path: root/drivers/s390/char/vmlogrdr.c
diff options
context:
space:
mode:
authorStefan Weinhuber <wein@de.ibm.com>2010-11-10 10:05:54 +0100
committerMartin Schwidefsky <sky@mschwide.boeblingen.de.ibm.com>2010-11-10 10:05:54 +0100
commitca768b663131ca644689fcadc9ca092dcc96a758 (patch)
treeaaf4136000d7f0204830978f304636beb4fd2368 /drivers/s390/char/vmlogrdr.c
parent16d2ce271c6b8b3527ed1461d03b5f373d53f78f (diff)
downloadlinux-ca768b663131ca644689fcadc9ca092dcc96a758.tar.gz
[S390] vmlogrdr: purge after recording is switched off
If automatic purge is enabled for a vmlogrdr device, old records are
purged before an IUCV recording service is switched on or off. If z/VM
generates a large number of records between purging and switching the
recording service off, these records remain queued, and may have a
negative performance impact on the z/VM system. To avoid this problem,
we need to purge the records after recording is switched off.

Signed-off-by: Stefan Weinhuber <wein@de.ibm.com>
Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/char/vmlogrdr.c')
-rw-r--r--drivers/s390/char/vmlogrdr.c36
1 files changed, 24 insertions, 12 deletions
diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c
index 9f661426e4a1..1cc726b98ec8 100644
--- a/drivers/s390/char/vmlogrdr.c
+++ b/drivers/s390/char/vmlogrdr.c
@@ -249,27 +249,25 @@ static int vmlogrdr_recording(struct vmlogrdr_priv_t * logptr,
 	char cp_command[80];
 	char cp_response[160];
 	char *onoff, *qid_string;
+	int rc;
 
-	memset(cp_command, 0x00, sizeof(cp_command));
-	memset(cp_response, 0x00, sizeof(cp_response));
-
-        onoff = ((action == 1) ? "ON" : "OFF");
+	onoff = ((action == 1) ? "ON" : "OFF");
 	qid_string = ((recording_class_AB == 1) ? " QID * " : "");
 
-        /*
+	/*
 	 * The recording commands needs to be called with option QID
 	 * for guests that have previlege classes A or B.
 	 * Purging has to be done as separate step, because recording
 	 * can't be switched on as long as records are on the queue.
 	 * Doing both at the same time doesn't work.
 	 */
-
-	if (purge) {
+	if (purge && (action == 1)) {
+		memset(cp_command, 0x00, sizeof(cp_command));
+		memset(cp_response, 0x00, sizeof(cp_response));
 		snprintf(cp_command, sizeof(cp_command),
 			 "RECORDING %s PURGE %s",
 			 logptr->recording_name,
 			 qid_string);
-
 		cpcmd(cp_command, cp_response, sizeof(cp_response), NULL);
 	}
 
@@ -279,19 +277,33 @@ static int vmlogrdr_recording(struct vmlogrdr_priv_t * logptr,
 		logptr->recording_name,
 		onoff,
 		qid_string);
-
 	cpcmd(cp_command, cp_response, sizeof(cp_response), NULL);
 	/* The recording command will usually answer with 'Command complete'
 	 * on success, but when the specific service was never connected
 	 * before then there might be an additional informational message
 	 * 'HCPCRC8072I Recording entry not found' before the
-         * 'Command complete'. So I use strstr rather then the strncmp.
+	 * 'Command complete'. So I use strstr rather then the strncmp.
 	 */
 	if (strstr(cp_response,"Command complete"))
-		return 0;
+		rc = 0;
 	else
-		return -EIO;
+		rc = -EIO;
+	/*
+	 * If we turn recording off, we have to purge any remaining records
+	 * afterwards, as a large number of queued records may impact z/VM
+	 * performance.
+	 */
+	if (purge && (action == 0)) {
+		memset(cp_command, 0x00, sizeof(cp_command));
+		memset(cp_response, 0x00, sizeof(cp_response));
+		snprintf(cp_command, sizeof(cp_command),
+			 "RECORDING %s PURGE %s",
+			 logptr->recording_name,
+			 qid_string);
+		cpcmd(cp_command, cp_response, sizeof(cp_response), NULL);
+	}
 
+	return rc;
 }