@@ -52,6 +52,8 @@
#define CREATE_TRACE_POINTS
#include <trace/events/oom.h>
+#include <linux/fdtable.h>
+
int sysctl_panic_on_oom;
int sysctl_oom_kill_allocating_task;
int sysctl_oom_dump_tasks = 1;
@@ -189,6 +191,19 @@ static bool should_dump_unreclaim_slab(void)
return (global_node_page_state_pages(NR_SLAB_UNRECLAIMABLE_B) > nr_lru);
}
+/* Sumup how much resources are bound by files opened. */
+static int oom_file_badness(const void *points, struct file *file, unsigned n)
+{
+ long badness;
+
+ if (!file->f_op->oom_badness)
+ return 0;
+
+ badness = file->f_op->oom_badness(file);
+ *((long *)points) += DIV_ROUND_UP(badness, file_count(file));
+ return 0;
+}
+
/**
* oom_badness - heuristic function to determine which candidate task to kill
* @p: task struct of which task we should calculate
@@ -229,6 +244,12 @@ long oom_badness(struct task_struct *p, unsigned long totalpages)
*/
points = get_mm_rss(p->mm) + get_mm_counter(p->mm, MM_SWAPENTS) +
mm_pgtables_bytes(p->mm) / PAGE_SIZE;
+
+ /*
+ * Add how much memory a task uses in opened files, e.g. device drivers.
+ */
+ iterate_fd(p->files, 0, oom_file_badness, &points);
+
task_unlock(p);
/* Normalize to oom_score_adj units */