summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--runtime/transport/ChangeLog6
-rw-r--r--runtime/transport/utt.c20
2 files changed, 26 insertions, 0 deletions
diff --git a/runtime/transport/ChangeLog b/runtime/transport/ChangeLog
index d16e3a3e..99b6e704 100644
--- a/runtime/transport/ChangeLog
+++ b/runtime/transport/ChangeLog
@@ -1,3 +1,9 @@
+2008-11-13 Masami Hiramatsu <mhiramat@redhat.com>
+
+ PR7016
+ * utt.c (utt_trace_setup): Check freeram and bufferram before
+ allocating relay buffers for avoiding OOM.
+
2008-11-12 Frank Ch. Eigler <fche@elastic.org>
* transport.c (_stp_cleanup_and_exit): Move debug print into
diff --git a/runtime/transport/utt.c b/runtime/transport/utt.c
index b8281bb4..642fe240 100644
--- a/runtime/transport/utt.c
+++ b/runtime/transport/utt.c
@@ -27,6 +27,7 @@
#include <linux/init.h>
#include <linux/debugfs.h>
#include <linux/relay.h>
+#include <linux/mm.h>
#include "utt.h"
static int utt_overwrite_flag = 0;
@@ -292,6 +293,8 @@ struct utt_trace *utt_trace_setup(struct utt_trace_setup *utts)
struct utt_trace *utt = NULL;
struct dentry *dir = NULL;
int ret = -EINVAL;
+ u64 npages;
+ struct sysinfo si;
if (!utts->buf_size || !utts->buf_nr)
goto err;
@@ -313,6 +316,23 @@ struct utt_trace *utt_trace_setup(struct utt_trace_setup *utts)
if (!utt->dropped_file)
goto err;
+ npages = utts->buf_size * utts->buf_nr;
+ if (!utts->is_global)
+ npages *= num_possible_cpus();
+ npages >>= PAGE_SHIFT;
+ si_meminfo(&si);
+#define MB(i) (unsigned long)((i) >> (20 - PAGE_SHIFT))
+ if (npages > (si.freeram + si.bufferram)) {
+ errk("Not enough free+buffered memory(%luMB) for log buffer\n",
+ MB(si.freeram + si.bufferram));
+ ret = -ENOMEM;
+ goto err;
+ } else if (npages > si.freeram) {
+ printk("Warning: log buffer size exceeds free memory(%luMB)\n",
+ MB(si.freeram));
+ /* exceeds freeram, but below freeram+bufferram */
+ }
+
#if (RELAYFS_CHANNEL_VERSION >= 7)
if (utts->is_global)
utt->rchan = relay_open("trace", dir, utts->buf_size, utts->buf_nr,