diff --git a/alloc_fail_loop.sh b/alloc_fail_loop.sh
new file mode 100755
index 0000000..b4909f0
--- /dev/null
+++ b/alloc_fail_loop.sh
@@ -0,0 +1,10 @@
+#!/bin/bash
+
+grep -rn --include='*.c' OBD_ALLOC /root/lustre-release/lustre |
+awk -F: '{ printf "%s:%d\n", $1, $2; }' |
+while read at; do
+    echo $at > /proc/fs/lustre/alloc_fail
+    sleep 1
+done
+
+echo > /proc/fs/lustre/alloc_fail
diff --git a/lustre/include/obd_support.h b/lustre/include/obd_support.h
index a20ec4c..c9b14a8 100644
--- a/lustre/include/obd_support.h
+++ b/lustre/include/obd_support.h
@@ -76,6 +76,8 @@ extern unsigned int obd_max_dirty_pages;
 extern atomic_t obd_dirty_pages;
 extern atomic_t obd_dirty_transit_pages;
 extern unsigned int obd_alloc_fail_rate;
+extern char obd_alloc_fail_file[PATH_MAX];
+extern unsigned int obd_alloc_fail_line;
 extern char obd_jobid_var[];
 
 /* lvfs.c */
@@ -676,8 +678,7 @@ do {									      \
 		kmalloc(size, flags | __GFP_ZERO) :			      \
 		cfs_cpt_malloc(cptab, cpt, size, flags | __GFP_ZERO);	      \
         if (likely((ptr) != NULL &&                                           \
-                   (!HAS_FAIL_ALLOC_FLAG || obd_alloc_fail_rate == 0 ||       \
-                    !obd_alloc_fail(ptr, #ptr, "km", size,                    \
+                   (!obd_alloc_fail(ptr, #ptr, "km", size,                    \
                                     __FILE__, __LINE__) ||                    \
                     OBD_FREE_RTN0(ptr)))){                                    \
                 OBD_ALLOC_POST(ptr, size, "kmalloced");                       \
diff --git a/lustre/obdclass/class_obd.c b/lustre/obdclass/class_obd.c
index ed02f4a..65bd282 100644
--- a/lustre/obdclass/class_obd.c
+++ b/lustre/obdclass/class_obd.c
@@ -77,6 +77,10 @@ DEFINE_SPINLOCK(obd_updatemax_lock);
 /* The following are visible and mutable through /proc/sys/lustre/. */
 unsigned int obd_alloc_fail_rate = 0;
 EXPORT_SYMBOL(obd_alloc_fail_rate);
+char obd_alloc_fail_file[PATH_MAX];
+EXPORT_SYMBOL(obd_alloc_fail_file);
+unsigned int obd_alloc_fail_line;
+EXPORT_SYMBOL(obd_alloc_fail_line);
 unsigned int obd_debug_peer_on_timeout;
 EXPORT_SYMBOL(obd_debug_peer_on_timeout);
 unsigned int obd_dump_on_timeout;
@@ -177,10 +181,17 @@ int lustre_get_jobid(char *jobid)
 }
 EXPORT_SYMBOL(lustre_get_jobid);
 
+static inline int obd_alloc_fail_at(const char *file, int line)
+{
+	return strcmp(file, obd_alloc_fail_file) == 0 &&
+		(line == obd_alloc_fail_line || obd_alloc_fail_line == -1);
+}
+
 int obd_alloc_fail(const void *ptr, const char *name, const char *type,
 		   size_t size, const char *file, int line)
 {
 	if (ptr == NULL ||
+	    obd_alloc_fail_at(file, line) ||
 	    (cfs_rand() & OBD_ALLOC_FAIL_MASK) < obd_alloc_fail_rate) {
 		CERROR("%s%salloc of %s ("LPU64" bytes) failed at %s:%d\n",
 		       ptr ? "force " :"", type, name, (__u64)size, file,
diff --git a/lustre/obdclass/linux/linux-module.c b/lustre/obdclass/linux/linux-module.c
index 0d7f656..557ce2c 100644
--- a/lustre/obdclass/linux/linux-module.c
+++ b/lustre/obdclass/linux/linux-module.c
@@ -321,6 +321,44 @@ obd_proc_jobid_var_seq_write(struct file *file, const char __user *buffer,
 }
 LPROC_SEQ_FOPS(obd_proc_jobid_var);
 
+static int obd_proc_alloc_fail_seq_show(struct seq_file *m, void *data)
+{
+	return seq_printf(m, "%s:%u\n",
+			  obd_alloc_fail_file, obd_alloc_fail_line);
+}
+
+static ssize_t
+obd_proc_alloc_fail_seq_write(struct file *file, const char __user *buf,
+			     size_t size, loff_t *off)
+{
+	char *s;
+
+	if (size == 0)
+		return 0;
+
+	if (!(size < sizeof(obd_alloc_fail_file)))
+		return -EINVAL;
+
+	obd_alloc_fail_line = 0;
+
+	memset(obd_alloc_fail_file, 0, sizeof(obd_alloc_fail_file));
+	if (copy_from_user(obd_alloc_fail_file, buf, size))
+		return -EFAULT;
+
+	s = obd_alloc_fail_file;
+	strsep(&s, ":");
+	if (s == NULL)
+		return size;
+
+	obd_alloc_fail_line = simple_strtoul(s, NULL, 0);
+
+	CERROR("alloc_fail_at = %s:%u\n",
+	       obd_alloc_fail_file, obd_alloc_fail_line);
+
+	return size;
+}
+LPROC_SEQ_FOPS(obd_proc_alloc_fail);
+
 /* Root for /proc/fs/lustre */
 struct proc_dir_entry *proc_lustre_root = NULL;
 EXPORT_SYMBOL(proc_lustre_root);
@@ -334,6 +372,10 @@ struct lprocfs_seq_vars lprocfs_base[] = {
 	  .fops	=	&obd_proc_health_fops	},
 	{ .name =	"jobid_var",
 	  .fops	=	&obd_proc_jobid_var_fops},
+	{
+		.name = "alloc_fail",
+		.fops =	&obd_proc_alloc_fail_fops,
+	},
 	{ 0 }
 };
 #else
