aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/s390
diff options
context:
space:
mode:
authorMichael Holzheu <holzheu@linux.vnet.ibm.com>2013-01-21 12:37:41 -0500
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2013-02-14 09:55:06 -0500
commitb4b3d128c821d70112ac0096d5c1440f5ed9f718 (patch)
tree1d19f77306bdf32d48cb6ea7f51703e8678a5fb3 /drivers/s390
parent0894b3ae776a60c6bad994e1d8f809ceb59904da (diff)
s390/zcore: Add hsa file
Under LPAR the zfcpdump HSA is a shared resource. Up to now the HSA memory is released when the zcore file is closed. Dump programs that know that they do not need the HSA memory any more (e.g. because they already dumped it) could release it earlier. This would allow other LPARs to use it again. To achieve this a new debugfs file "hsa" is added that can be used to read the HSA size and to release the HSA by writing "0" into the file. Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
Diffstat (limited to 'drivers/s390')
-rw-r--r--drivers/s390/char/zcore.c62
1 files changed, 59 insertions, 3 deletions
diff --git a/drivers/s390/char/zcore.c b/drivers/s390/char/zcore.c
index e3b9308b0fe3..681749e7f6dd 100644
--- a/drivers/s390/char/zcore.c
+++ b/drivers/s390/char/zcore.c
@@ -62,6 +62,7 @@ static struct dentry *zcore_dir;
62static struct dentry *zcore_file; 62static struct dentry *zcore_file;
63static struct dentry *zcore_memmap_file; 63static struct dentry *zcore_memmap_file;
64static struct dentry *zcore_reipl_file; 64static struct dentry *zcore_reipl_file;
65static struct dentry *zcore_hsa_file;
65static struct ipl_parameter_block *ipl_block; 66static struct ipl_parameter_block *ipl_block;
66 67
67/* 68/*
@@ -77,6 +78,8 @@ static int memcpy_hsa(void *dest, unsigned long src, size_t count, int mode)
77 int offs, blk_num; 78 int offs, blk_num;
78 static char buf[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE))); 79 static char buf[PAGE_SIZE] __attribute__((__aligned__(PAGE_SIZE)));
79 80
81 if (!hsa_available)
82 return -ENODATA;
80 if (count == 0) 83 if (count == 0)
81 return 0; 84 return 0;
82 85
@@ -278,6 +281,15 @@ next:
278} 281}
279 282
280/* 283/*
284 * Release the HSA
285 */
286static void release_hsa(void)
287{
288 diag308(DIAG308_REL_HSA, NULL);
289 hsa_available = 0;
290}
291
292/*
281 * Read routine for zcore character device 293 * Read routine for zcore character device
282 * First 4K are dump header 294 * First 4K are dump header
283 * Next 32MB are HSA Memory 295 * Next 32MB are HSA Memory
@@ -363,8 +375,8 @@ static int zcore_open(struct inode *inode, struct file *filp)
363 375
364static int zcore_release(struct inode *inode, struct file *filep) 376static int zcore_release(struct inode *inode, struct file *filep)
365{ 377{
366 diag308(DIAG308_REL_HSA, NULL); 378 if (hsa_available)
367 hsa_available = 0; 379 release_hsa();
368 return 0; 380 return 0;
369} 381}
370 382
@@ -474,6 +486,41 @@ static const struct file_operations zcore_reipl_fops = {
474 .llseek = no_llseek, 486 .llseek = no_llseek,
475}; 487};
476 488
489static ssize_t zcore_hsa_read(struct file *filp, char __user *buf,
490 size_t count, loff_t *ppos)
491{
492 static char str[18];
493
494 if (hsa_available)
495 snprintf(str, sizeof(str), "%lx\n", ZFCPDUMP_HSA_SIZE);
496 else
497 snprintf(str, sizeof(str), "0\n");
498 return simple_read_from_buffer(buf, count, ppos, str, strlen(str));
499}
500
501static ssize_t zcore_hsa_write(struct file *filp, const char __user *buf,
502 size_t count, loff_t *ppos)
503{
504 char value;
505
506 if (*ppos != 0)
507 return -EPIPE;
508 if (copy_from_user(&value, buf, 1))
509 return -EFAULT;
510 if (value != '0')
511 return -EINVAL;
512 release_hsa();
513 return count;
514}
515
516static const struct file_operations zcore_hsa_fops = {
517 .owner = THIS_MODULE,
518 .write = zcore_hsa_write,
519 .read = zcore_hsa_read,
520 .open = nonseekable_open,
521 .llseek = no_llseek,
522};
523
477#ifdef CONFIG_32BIT 524#ifdef CONFIG_32BIT
478 525
479static void __init set_lc_mask(struct save_area *map) 526static void __init set_lc_mask(struct save_area *map)
@@ -658,6 +705,7 @@ static int __init zcore_init(void)
658 rc = check_sdias(); 705 rc = check_sdias();
659 if (rc) 706 if (rc)
660 goto fail; 707 goto fail;
708 hsa_available = 1;
661 709
662 rc = memcpy_hsa_kernel(&arch, __LC_AR_MODE_ID, 1); 710 rc = memcpy_hsa_kernel(&arch, __LC_AR_MODE_ID, 1);
663 if (rc) 711 if (rc)
@@ -714,9 +762,16 @@ static int __init zcore_init(void)
714 rc = -ENOMEM; 762 rc = -ENOMEM;
715 goto fail_memmap_file; 763 goto fail_memmap_file;
716 } 764 }
717 hsa_available = 1; 765 zcore_hsa_file = debugfs_create_file("hsa", S_IRUSR|S_IWUSR, zcore_dir,
766 NULL, &zcore_hsa_fops);
767 if (!zcore_hsa_file) {
768 rc = -ENOMEM;
769 goto fail_reipl_file;
770 }
718 return 0; 771 return 0;
719 772
773fail_reipl_file:
774 debugfs_remove(zcore_reipl_file);
720fail_memmap_file: 775fail_memmap_file:
721 debugfs_remove(zcore_memmap_file); 776 debugfs_remove(zcore_memmap_file);
722fail_file: 777fail_file:
@@ -733,6 +788,7 @@ static void __exit zcore_exit(void)
733 debug_unregister(zcore_dbf); 788 debug_unregister(zcore_dbf);
734 sclp_sdias_exit(); 789 sclp_sdias_exit();
735 free_page((unsigned long) ipl_block); 790 free_page((unsigned long) ipl_block);
791 debugfs_remove(zcore_hsa_file);
736 debugfs_remove(zcore_reipl_file); 792 debugfs_remove(zcore_reipl_file);
737 debugfs_remove(zcore_memmap_file); 793 debugfs_remove(zcore_memmap_file);
738 debugfs_remove(zcore_file); 794 debugfs_remove(zcore_file);