kdump/kdump-count-framebuffer.patch
Petr Tesařík 0a47303e13 Accepting request 248055 from home:ptesarik:branches:Kernel:kdump
- kdump-count-const-slabs.patch: Take constant-size slabs into
  account for "kdump calibrate" (bnc#879460).

- kdump-count-framebuffer.patch: Take framebuffer size into account
  for "kdumptool calibrate" (bnc#879460).

OBS-URL: https://build.opensuse.org/request/show/248055
OBS-URL: https://build.opensuse.org/package/show/Kernel:kdump/kdump?expand=0&rev=104
2014-09-08 15:47:03 +00:00

229 lines
6.0 KiB
Diff

From: Petr Tesarik <ptesarik@suse.cz>
Date: Mon Sep 8 09:28:04 2014 +0200
Subject: Take framebuffer size into account for "kdumptool calibrate"
References: bnc#879460
Patch-mainline: v0.8.16
Git-commit: 77ad2fff73fc6dd2dd0615e56967721ba9b96d83
Git-commit: 7cd4e826671ded8fe36a4b4bdeef1223ce8397ca
Depending on the resolution, framebuffer(s) may considerably influence
kdump kernel requirements.
Note that there is no framebuffer on z/Series, so after reading sysfs
fails, the default size for s390(x) is zero.
Signed-off-by: Petr Tesarik <ptesarik@suse.cz>
---
kdumptool/calibrate.cc | 153 +++++++++++++++++++++++++++++++++++++++++++++++++
kdumptool/fileutil.cc | 2
kdumptool/fileutil.h | 2
3 files changed, 155 insertions(+), 2 deletions(-)
--- a/kdumptool/fileutil.cc
+++ b/kdumptool/fileutil.cc
@@ -295,7 +295,7 @@ FilePath FilePath::getCanonicalPath(cons
}
// -----------------------------------------------------------------------------
-StringVector FilePath::listDir(const ListDirFilter &filter)
+StringVector FilePath::listDir(const ListDirFilter &filter) const
throw (KError)
{
StringVector v;
--- a/kdumptool/fileutil.h
+++ b/kdumptool/fileutil.h
@@ -224,7 +224,7 @@ class FilePath : public KString {
* list, @c false if all files should be included
* @exception KError if something went wrong
*/
- StringVector listDir(const ListDirFilter &filter)
+ StringVector listDir(const ListDirFilter &filter) const
throw (KError);
/**
--- a/kdumptool/calibrate.cc
+++ b/kdumptool/calibrate.cc
@@ -19,7 +19,10 @@
#include <iostream>
#include <fstream>
#include <cerrno>
+#include <cstring>
+#include <cstdlib>
#include <unistd.h>
+#include <dirent.h>
#include "subcommand.h"
#include "debug.h"
@@ -173,6 +176,13 @@ static inline unsigned long s390x_align_
// Estimated non-changing dynamic data (sysfs, procfs, etc.)
#define KERNEL_DYNAMIC_KB MB(4)
+// Default framebuffer size: 1024x768 @ 32bpp, except on mainframe
+#if defined(__s390__) || defined(__s390x__)
+# define DEF_FRAMEBUFFER_KB 0
+#else
+# define DEF_FRAMEBUFFER_KB (768UL*4)
+#endif
+
// large hashes, default settings: -> per MiB
// PID: sizeof(void*) for each 256 KiB 4
// Dentry cache: sizeof(void*) for each 8 KiB 128
@@ -303,6 +313,141 @@ unsigned long SystemCPU::count(const cha
}
//}}}
+//{{{ Framebuffer --------------------------------------------------------------
+
+class Framebuffer {
+
+ public:
+ /**
+ * Initialize a new Framebuffer object.
+ *
+ * @param[in] fbpath Framebuffer sysfs directory path
+ */
+ Framebuffer(const char *fbpath)
+ throw ()
+ : m_dir(fbpath)
+ {}
+
+ protected:
+ /**
+ * Path to the framebuffer device base directory
+ */
+ const FilePath m_dir;
+
+ public:
+ /**
+ * Get length of the framebuffer [in bytes].
+ */
+ unsigned long size(void) const;
+};
+
+// -----------------------------------------------------------------------------
+unsigned long Framebuffer::size(void) const
+{
+ FilePath fp;
+ std::ifstream f;
+ unsigned long width, height, stride;
+ char sep;
+
+ fp.assign(m_dir);
+ fp.appendPath("virtual_size");
+ f.open(fp.c_str());
+ if (!f)
+ throw KError(fp + ": Open failed");
+ f >> width >> sep >> height;
+ f.close();
+ if (f.bad())
+ throw KError(fp + ": Read failed");
+ else if (!f || sep != ',')
+ throw KError(fp + ": Invalid content!");
+ Debug::debug()->dbg("Framebuffer virtual size: %lux%lu", width, height);
+
+ fp.assign(m_dir);
+ fp.appendPath("stride");
+ f.open(fp.c_str());
+ if (!f)
+ throw KError(fp + ": Open failed");
+ f >> stride;
+ f.close();
+ if (f.bad())
+ throw KError(fp + ": Read failed");
+ else if (!f || sep != ',')
+ throw KError(fp + ": Invalid content!");
+ Debug::debug()->dbg("Framebuffer stride: %lu bytes", stride);
+
+ return stride * height;
+}
+
+//}}}
+//{{{ Framebuffers -------------------------------------------------------------
+
+class Framebuffers {
+
+ public:
+ /**
+ * Initialize a new Framebuffer object.
+ *
+ * @param[in] sysdir Mount point for sysfs
+ */
+ Framebuffers(const char *sysdir = "/sys")
+ throw ()
+ : m_fbdir(FilePath(sysdir).appendPath("class/graphics"))
+ {}
+
+ protected:
+ /**
+ * Path to the base directory with links to framebuffer devices
+ */
+ const FilePath m_fbdir;
+
+ /**
+ * Filter only valid framebuffer device name
+ */
+ class DirFilter : public ListDirFilter {
+
+ public:
+ virtual ~DirFilter()
+ {}
+
+ bool test(const struct dirent *d) const
+ {
+ char *end;
+ if (strncmp(d->d_name, "fb", 2))
+ return false;
+ strtoul(d->d_name + 2, &end, 10);
+ return (*end == '\0' && end != d->d_name + 2);
+ }
+ };
+
+ public:
+ /**
+ * Get size of all framebuffers [in bytes].
+ */
+ unsigned long size(void) const;
+};
+
+// -----------------------------------------------------------------------------
+unsigned long Framebuffers::size(void) const
+{
+ Debug::debug()->trace("Framebuffers::size()");
+
+ unsigned long ret = 0UL;
+
+ StringVector v = m_fbdir.listDir(DirFilter());
+ for (StringVector::const_iterator it = v.begin(); it != v.end(); ++it) {
+ Debug::debug()->dbg("Found framebuffer: %s", it->c_str());
+
+ FilePath fp(m_fbdir);
+ fp.appendPath(*it);
+ Framebuffer fb(fp.c_str());
+ ret += fb.size();
+ }
+
+ Debug::debug()->dbg("Total size of all framebuffers: %lu bytes", ret);
+ return ret;
+}
+
+//}}}
//{{{ Calibrate ----------------------------------------------------------------
// -----------------------------------------------------------------------------
@@ -345,6 +490,14 @@ void Calibrate::execute()
// Run-time kernel requirements
required = KERNEL_KB + ramfs + KERNEL_DYNAMIC_KB;
+ try {
+ Framebuffers fb;
+ required += fb.size() / 1024UL;
+ } catch(KError e) {
+ Debug::debug()->dbg("Cannot get framebuffer size: %s", e.what());
+ required += DEF_FRAMEBUFFER_KB;
+ }
+
// Add memory based on CPU count
unsigned long cpus;
if (CAN_REDUCE_CPUS) {