aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390/char/sclp.c
diff options
context:
space:
mode:
authorMartin Schwidefsky <schwidefsky@de.ibm.com>2013-05-24 06:30:03 -0400
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2013-06-26 15:10:03 -0400
commit25b41a7b67ee4f4d12cee8a4b8b5929e36c27e29 (patch)
tree519be1cacdb7a23ff314ade0cec813c6d59b1af9 /drivers/s390/char/sclp.c
parent92820a5f99748b02a3713a314d81e2fd0b6b2f80 (diff)
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.c')
-rw-r--r--drivers/s390/char/sclp.c69
1 files changed, 69 insertions, 0 deletions
diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c
index bd6871bf545a..a77febeead1f 100644
--- a/drivers/s390/char/sclp.c
+++ b/drivers/s390/char/sclp.c
@@ -50,11 +50,42 @@ static char sclp_init_sccb[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
50/* Suspend request */ 50/* Suspend request */
51static DECLARE_COMPLETION(sclp_request_queue_flushed); 51static DECLARE_COMPLETION(sclp_request_queue_flushed);
52 52
53/* Number of console pages to allocate, used by sclp_con.c and sclp_vt220.c */
54int sclp_console_pages = SCLP_CONSOLE_PAGES;
55/* Flag to indicate if buffer pages are dropped on buffer full condition */
56int sclp_console_drop = 0;
57/* Number of times the console dropped buffer pages */
58unsigned long sclp_console_full;
59
53static void sclp_suspend_req_cb(struct sclp_req *req, void *data) 60static void sclp_suspend_req_cb(struct sclp_req *req, void *data)
54{ 61{
55 complete(&sclp_request_queue_flushed); 62 complete(&sclp_request_queue_flushed);
56} 63}
57 64
65static int __init sclp_setup_console_pages(char *str)
66{
67 int pages, rc;
68
69 rc = kstrtoint(str, 0, &pages);
70 if (!rc && pages >= SCLP_CONSOLE_PAGES)
71 sclp_console_pages = pages;
72 return 1;
73}
74
75__setup("sclp_con_pages=", sclp_setup_console_pages);
76
77static int __init sclp_setup_console_drop(char *str)
78{
79 int drop, rc;
80
81 rc = kstrtoint(str, 0, &drop);
82 if (!rc && drop)
83 sclp_console_drop = 1;
84 return 1;
85}
86
87__setup("sclp_con_drop=", sclp_setup_console_drop);
88
58static struct sclp_req sclp_suspend_req; 89static struct sclp_req sclp_suspend_req;
59 90
60/* Timer for request retries. */ 91/* Timer for request retries. */
@@ -1013,11 +1044,47 @@ static const struct dev_pm_ops sclp_pm_ops = {
1013 .restore = sclp_restore, 1044 .restore = sclp_restore,
1014}; 1045};
1015 1046
1047static ssize_t sclp_show_console_pages(struct device_driver *dev, char *buf)
1048{
1049 return sprintf(buf, "%i\n", sclp_console_pages);
1050}
1051
1052static DRIVER_ATTR(con_pages, S_IRUSR, sclp_show_console_pages, NULL);
1053
1054static ssize_t sclp_show_con_drop(struct device_driver *dev, char *buf)
1055{
1056 return sprintf(buf, "%i\n", sclp_console_drop);
1057}
1058
1059static DRIVER_ATTR(con_drop, S_IRUSR, sclp_show_con_drop, NULL);
1060
1061static ssize_t sclp_show_console_full(struct device_driver *dev, char *buf)
1062{
1063 return sprintf(buf, "%lu\n", sclp_console_full);
1064}
1065
1066static DRIVER_ATTR(con_full, S_IRUSR, sclp_show_console_full, NULL);
1067
1068static struct attribute *sclp_drv_attrs[] = {
1069 &driver_attr_con_pages.attr,
1070 &driver_attr_con_drop.attr,
1071 &driver_attr_con_full.attr,
1072 NULL,
1073};
1074static struct attribute_group sclp_drv_attr_group = {
1075 .attrs = sclp_drv_attrs,
1076};
1077static const struct attribute_group *sclp_drv_attr_groups[] = {
1078 &sclp_drv_attr_group,
1079 NULL,
1080};
1081
1016static struct platform_driver sclp_pdrv = { 1082static struct platform_driver sclp_pdrv = {
1017 .driver = { 1083 .driver = {
1018 .name = "sclp", 1084 .name = "sclp",
1019 .owner = THIS_MODULE, 1085 .owner = THIS_MODULE,
1020 .pm = &sclp_pm_ops, 1086 .pm = &sclp_pm_ops,
1087 .groups = sclp_drv_attr_groups,
1021 }, 1088 },
1022}; 1089};
1023 1090
@@ -1096,10 +1163,12 @@ static __init int sclp_initcall(void)
1096 rc = platform_driver_register(&sclp_pdrv); 1163 rc = platform_driver_register(&sclp_pdrv);
1097 if (rc) 1164 if (rc)
1098 return rc; 1165 return rc;
1166
1099 sclp_pdev = platform_device_register_simple("sclp", -1, NULL, 0); 1167 sclp_pdev = platform_device_register_simple("sclp", -1, NULL, 0);
1100 rc = IS_ERR(sclp_pdev) ? PTR_ERR(sclp_pdev) : 0; 1168 rc = IS_ERR(sclp_pdev) ? PTR_ERR(sclp_pdev) : 0;
1101 if (rc) 1169 if (rc)
1102 goto fail_platform_driver_unregister; 1170 goto fail_platform_driver_unregister;
1171
1103 rc = atomic_notifier_chain_register(&panic_notifier_list, 1172 rc = atomic_notifier_chain_register(&panic_notifier_list,
1104 &sclp_on_panic_nb); 1173 &sclp_on_panic_nb);
1105 if (rc) 1174 if (rc)