summaryrefslogtreecommitdiff
path: root/drivers/s390/char/sclp_vt220.c
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2013-05-24 14:30:03 +0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2013-06-26 23:10:03 +0400
commit25b41a7b67ee4f4d12cee8a4b8b5929e36c27e29 (patch)
tree519be1cacdb7a23ff314ade0cec813c6d59b1af9 /drivers/s390/char/sclp_vt220.c
parent92820a5f99748b02a3713a314d81e2fd0b6b2f80 (diff)
downloadlinux-25b41a7b67ee4f4d12cee8a4b8b5929e36c27e29.tar.xz
s390/sclp: add parameter to specify number of buffer pages
Add a kernel parameter to be able to specify the number of pages to be used as output buffer by the line-mode sclp driver and the vt220 sclp driver. The current number of output pages is 6, if the service element is unavailable the boot messages alone can fill up the output buffer. If this happens the system blocks until the service element is working again. For a large LPAR with many devices it is sensible to have the ability to increase the output buffer size. To help to debug this situation add a counter for the page-pool-empty situation and make it available as a sclp driver attribute. To avoid the system to stall until the service element works again add another kernel parameter to allow to drop output buffers. Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390/char/sclp_vt220.c')
-rw-r--r--drivers/s390/char/sclp_vt220.c39
1 files changed, 34 insertions, 5 deletions
diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c
index 5aaaa2ec8df4..4eed38cd0af6 100644
--- a/drivers/s390/char/sclp_vt220.c
+++ b/drivers/s390/char/sclp_vt220.c
@@ -362,6 +362,31 @@ sclp_vt220_timeout(unsigned long data)
#define BUFFER_MAX_DELAY HZ/20
+/*
+ * Drop oldest console buffer if sclp_con_drop is set
+ */
+static int
+sclp_vt220_drop_buffer(void)
+{
+ struct list_head *list;
+ struct sclp_vt220_request *request;
+ void *page;
+
+ if (!sclp_console_drop)
+ return 0;
+ list = sclp_vt220_outqueue.next;
+ if (sclp_vt220_queue_running)
+ /* The first element is in I/O */
+ list = list->next;
+ if (list == &sclp_vt220_outqueue)
+ return 0;
+ list_del(list);
+ request = list_entry(list, struct sclp_vt220_request, list);
+ page = request->sclp_req.sccb;
+ list_add_tail((struct list_head *) page, &sclp_vt220_empty);
+ return 1;
+}
+
/*
* Internal implementation of the write function. Write COUNT bytes of data
* from memory at BUF
@@ -390,12 +415,16 @@ __sclp_vt220_write(const unsigned char *buf, int count, int do_schedule,
do {
/* Create an sclp output buffer if none exists yet */
if (sclp_vt220_current_request == NULL) {
+ if (list_empty(&sclp_vt220_empty))
+ sclp_console_full++;
while (list_empty(&sclp_vt220_empty)) {
- spin_unlock_irqrestore(&sclp_vt220_lock, flags);
if (may_fail || sclp_vt220_suspended)
goto out;
- else
- sclp_sync_wait();
+ if (sclp_vt220_drop_buffer())
+ break;
+ spin_unlock_irqrestore(&sclp_vt220_lock, flags);
+
+ sclp_sync_wait();
spin_lock_irqsave(&sclp_vt220_lock, flags);
}
page = (void *) sclp_vt220_empty.next;
@@ -428,8 +457,8 @@ __sclp_vt220_write(const unsigned char *buf, int count, int do_schedule,
sclp_vt220_timer.expires = jiffies + BUFFER_MAX_DELAY;
add_timer(&sclp_vt220_timer);
}
- spin_unlock_irqrestore(&sclp_vt220_lock, flags);
out:
+ spin_unlock_irqrestore(&sclp_vt220_lock, flags);
return overall_written;
}
@@ -803,7 +832,7 @@ sclp_vt220_con_init(void)
if (!CONSOLE_IS_SCLP)
return 0;
- rc = __sclp_vt220_init(MAX_CONSOLE_PAGES);
+ rc = __sclp_vt220_init(sclp_console_pages);
if (rc)
return rc;
/* Attach linux console */