]> git.karo-electronics.de Git - karo-tx-linux.git/commitdiff
s390,sclp: add parameter to specify number of buffer pages
authorMartin Schwidefsky <schwidefsky@de.ibm.com>
Fri, 24 May 2013 10:30:03 +0000 (12:30 +0200)
committerMartin Schwidefsky <schwidefsky@de.ibm.com>
Mon, 10 Jun 2013 14:06:13 +0000 (16:06 +0200)
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.

Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
drivers/s390/char/sclp.c
drivers/s390/char/sclp.h
drivers/s390/char/sclp_con.c
drivers/s390/char/sclp_vt220.c

index bd6871bf545a67200a5e4af4c672fb18f0193f0c..723f657cce941da1491088a9735227ead46cec1a 100644 (file)
@@ -50,6 +50,23 @@ static char sclp_init_sccb[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
 /* Suspend request */
 static DECLARE_COMPLETION(sclp_request_queue_flushed);
 
+/* Number of console pages to allocate, used by sclp_con.c and sclp_vt220.c */
+int sclp_console_pages = SCLP_CONSOLE_PAGES;
+/* Number of times the console pages pool run empty */
+unsigned long sclp_console_pages_empty;
+
+static int __init sclp_setup_console_pages(char *str)
+{
+       int pages;
+
+       pages = simple_strtoul(str, &str, 0);
+       if (pages >= 6)
+               sclp_console_pages = pages;
+       return 1;
+}
+
+__setup("sclp_console_pages=", sclp_setup_console_pages);
+
 static void sclp_suspend_req_cb(struct sclp_req *req, void *data)
 {
        complete(&sclp_request_queue_flushed);
@@ -1013,11 +1030,41 @@ static const struct dev_pm_ops sclp_pm_ops = {
        .restore        = sclp_restore,
 };
 
+static ssize_t sclp_show_console_pages(struct device_driver *dev, char *buf)
+{
+       return sprintf(buf, "%i\n", sclp_console_pages);
+}
+
+static DRIVER_ATTR(console_pages, S_IRUSR, sclp_show_console_pages, NULL);
+
+static ssize_t sclp_show_console_pages_empty(struct device_driver *dev,
+                                            char *buf)
+{
+       return sprintf(buf, "%lu\n", sclp_console_pages_empty);
+}
+
+static DRIVER_ATTR(console_pages_empty, S_IRUSR,
+                  sclp_show_console_pages_empty, NULL);
+
+static struct attribute *sclp_drv_attrs[] = {
+       &driver_attr_console_pages.attr,
+       &driver_attr_console_pages_empty.attr,
+       NULL,
+};
+static struct attribute_group sclp_drv_attr_group = {
+       .attrs = sclp_drv_attrs,
+};
+static const struct attribute_group *sclp_drv_attr_groups[] = {
+       &sclp_drv_attr_group,
+       NULL,
+};
+
 static struct platform_driver sclp_pdrv = {
        .driver = {
                .name   = "sclp",
                .owner  = THIS_MODULE,
                .pm     = &sclp_pm_ops,
+               .groups = sclp_drv_attr_groups,
        },
 };
 
@@ -1096,10 +1143,12 @@ static __init int sclp_initcall(void)
        rc = platform_driver_register(&sclp_pdrv);
        if (rc)
                return rc;
+
        sclp_pdev = platform_device_register_simple("sclp", -1, NULL, 0);
        rc = IS_ERR(sclp_pdev) ? PTR_ERR(sclp_pdev) : 0;
        if (rc)
                goto fail_platform_driver_unregister;
+
        rc = atomic_notifier_chain_register(&panic_notifier_list,
                                            &sclp_on_panic_nb);
        if (rc)
index 25bcd4c0ed82d35f522f4d0efdd7477ec6076a01..d35495076ab6dea67172d2913faeb1bfa6c2ba83 100644 (file)
@@ -15,7 +15,7 @@
 
 /* maximum number of pages concerning our own memory management */
 #define MAX_KMEM_PAGES (sizeof(unsigned long) << 3)
-#define MAX_CONSOLE_PAGES      6
+#define SCLP_CONSOLE_PAGES     6
 
 #define EVTYP_OPCMD            0x01
 #define EVTYP_MSG              0x02
@@ -175,6 +175,9 @@ int sclp_service_call(sclp_cmdw_t command, void *sccb);
 int sclp_sdias_init(void);
 void sclp_sdias_exit(void);
 
+extern int sclp_console_pages;
+extern unsigned long sclp_console_pages_empty;
+
 /* useful inlines */
 
 /* VM uses EBCDIC 037, LPAR+native(SE+HMC) use EBCDIC 500 */
index ecf45c54f8c469c84da45049e006225593283a90..8e4639f439a11bf5af7711340f3c26cf5403d789 100644 (file)
@@ -150,6 +150,8 @@ sclp_console_write(struct console *console, const char *message,
        do {
                /* make sure we have a console output buffer */
                if (sclp_conbuf == NULL) {
+                       if (list_empty(&sclp_con_pages))
+                               sclp_console_pages_empty++;
                        while (list_empty(&sclp_con_pages)) {
                                if (sclp_con_suspended)
                                        goto out;
@@ -297,7 +299,7 @@ sclp_console_init(void)
                return rc;
        /* Allocate pages for output buffering */
        INIT_LIST_HEAD(&sclp_con_pages);
-       for (i = 0; i < MAX_CONSOLE_PAGES; i++) {
+       for (i = 0; i < sclp_console_pages; i++) {
                page = (void *) get_zeroed_page(GFP_KERNEL | GFP_DMA);
                list_add_tail(page, &sclp_con_pages);
        }
index 5aaaa2ec8df44f4547c70b9f80d5c628c6d9d591..1953b1eb8ae01a5397c12e777fd2eed51a4017fd 100644 (file)
@@ -390,6 +390,8 @@ __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_pages_empty++;
                        while (list_empty(&sclp_vt220_empty)) {
                                spin_unlock_irqrestore(&sclp_vt220_lock, flags);
                                if (may_fail || sclp_vt220_suspended)
@@ -803,7 +805,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 */