From: Hendrik Brueckner <brueckner@redhat.com> Date: Thu, 18 Nov 2010 14:36:07 -0500 Subject: [s390] vmlogrdr: purge after recording is switched off Message-id: <20101118143605.GA14428@redhat.com> Patchwork-id: 29487 O-Subject: [RHEL5.6 PATCH 1/1] [s390x] vmlogrdr: purge after recording is switched off Bugzilla: 653479 Description ----------- 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 off the recording service, these records remain queued, and might have a negative performance impact on the z/VM system. There is a small time gap between old records being purged and creation of new records being stopped. On a busy system this gap might be large enough to cause a problem. To avoid this problem, purge the records after recording is switched off. Bugzilla -------- BZ 653479 https://bugzilla.redhat.com/show_bug.cgi?id=653479 Upstream status of the patch ---------------------------- The patch is upstream as of kernel version 2.6.37 http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=ca768b663131ca644689fcadc9ca092dcc96a758 Test status ----------- The patch has been tested and fixes the problem. The fix has been verified by the IBM test department. diff --git a/drivers/s390/char/vmlogrdr.c b/drivers/s390/char/vmlogrdr.c index 7ecd27b..969953b 100644 --- a/drivers/s390/char/vmlogrdr.c +++ b/drivers/s390/char/vmlogrdr.c @@ -247,9 +247,7 @@ static int vmlogrdr_recording(struct vmlogrdr_priv_t * logptr, char cp_command[80]; char cp_response[160]; char *onoff, *qid_string; - - memset(cp_command, 0x00, sizeof(cp_command)); - memset(cp_response, 0x00, sizeof(cp_response)); + int rc; onoff = ((action == 1) ? "ON" : "OFF"); qid_string = ((recording_class_AB == 1) ? " QID * " : ""); @@ -261,8 +259,9 @@ static int vmlogrdr_recording(struct vmlogrdr_priv_t * logptr, * 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, @@ -281,7 +280,6 @@ static int vmlogrdr_recording(struct vmlogrdr_priv_t * logptr, logptr->recording_name, onoff, qid_string); - printk (KERN_DEBUG "vmlogrdr: recording command: %s\n", cp_command); cpcmd(cp_command, cp_response, sizeof(cp_response), NULL); printk (KERN_DEBUG "vmlogrdr: recording response: %s", @@ -293,10 +291,29 @@ static int vmlogrdr_recording(struct vmlogrdr_priv_t * logptr, * '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); + printk (KERN_DEBUG "vmlogrdr: recording command: %s\n", + cp_command); + cpcmd(cp_command, cp_response, sizeof(cp_response), NULL); + printk (KERN_DEBUG "vmlogrdr: recording response: %s", + cp_response); + } + return rc; }