Re: [BUG] mm: bdi: export BDI attributes in sysfs

Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
From: Miklos Szeredi
Date: Thursday, May 15, 2008 - 11:53 am

> About 1 in 4 times, when turning the power back


I suspect this is because there's a race between the show/store
functions and dev_set_drvdata() in bdi_register().

Could you try this patch to verify that this is indeed the problem?

This is not meant as a final solution, I'm sure Greg or Kay can help
find a better solution.

Thanks,
Miklos


Index: linux-2.6/mm/backing-dev.c
===================================================================
--- linux-2.6.orig/mm/backing-dev.c	2008-05-14 12:49:33.000000000 +0200
+++ linux-2.6/mm/backing-dev.c	2008-05-15 20:37:55.000000000 +0200
@@ -15,6 +15,7 @@ static struct class *bdi_class;
 #include <linux/seq_file.h>
 
 static struct dentry *bdi_debug_root;
+static DEFINE_MUTEX(bdi_dev_mutex);
 
 static void bdi_debug_init(void)
 {
@@ -84,11 +85,19 @@ static inline void bdi_debug_unregister(
 }
 #endif
 
+static struct backing_dev_info *dev_get_bdi(struct device *dev)
+{
+	mutex_lock(&bdi_dev_mutex);
+	mutex_unlock(&bdi_dev_mutex);
+
+	return dev_get_drvdata(dev);
+}
+
 static ssize_t read_ahead_kb_store(struct device *dev,
 				  struct device_attribute *attr,
 				  const char *buf, size_t count)
 {
-	struct backing_dev_info *bdi = dev_get_drvdata(dev);
+	struct backing_dev_info *bdi = dev_get_bdi(dev);
 	char *end;
 	unsigned long read_ahead_kb;
 	ssize_t ret = -EINVAL;
@@ -107,7 +116,7 @@ static ssize_t read_ahead_kb_store(struc
 static ssize_t name##_show(struct device *dev,				\
 			   struct device_attribute *attr, char *page)	\
 {									\
-	struct backing_dev_info *bdi = dev_get_drvdata(dev);		\
+	struct backing_dev_info *bdi = dev_get_bdi(dev);		\
 									\
 	return snprintf(page, PAGE_SIZE-1, "%lld\n", (long long)expr);	\
 }
@@ -117,7 +126,7 @@ BDI_SHOW(read_ahead_kb, K(bdi->ra_pages)
 static ssize_t min_ratio_store(struct device *dev,
 		struct device_attribute *attr, const char *buf, size_t count)
 {
-	struct backing_dev_info *bdi = dev_get_drvdata(dev);
+	struct backing_dev_info *bdi = dev_get_bdi(dev);
 	char *end;
 	unsigned int ratio;
 	ssize_t ret = -EINVAL;
@@ -135,7 +144,7 @@ BDI_SHOW(min_ratio, bdi->min_ratio)
 static ssize_t max_ratio_store(struct device *dev,
 		struct device_attribute *attr, const char *buf, size_t count)
 {
-	struct backing_dev_info *bdi = dev_get_drvdata(dev);
+	struct backing_dev_info *bdi = dev_get_bdi(dev);
 	char *end;
 	unsigned int ratio;
 	ssize_t ret = -EINVAL;
@@ -184,6 +193,7 @@ int bdi_register(struct backing_dev_info
 	if (!name)
 		return -ENOMEM;
 
+	mutex_lock(&bdi_dev_mutex);
 	dev = device_create(bdi_class, parent, MKDEV(0, 0), name);
 	if (IS_ERR(dev)) {
 		ret = PTR_ERR(dev);
@@ -195,6 +205,7 @@ int bdi_register(struct backing_dev_info
 	bdi_debug_register(bdi, name);
 
 exit:
+	mutex_unlock(&bdi_dev_mutex);
 	kfree(name);
 	return ret;
 }


--
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
Re: [BUG] mm: bdi: export BDI attributes in sysfs, Arthur Jones, (Wed May 14, 7:40 am)
Re: [BUG] mm: bdi: export BDI attributes in sysfs, Miklos Szeredi, (Thu May 15, 11:53 am)
Re: [BUG] mm: bdi: export BDI attributes in sysfs, Linus Torvalds, (Thu May 15, 12:18 pm)
Re: [BUG] mm: bdi: export BDI attributes in sysfs, Miklos Szeredi, (Thu May 15, 12:27 pm)
Re: [BUG] mm: bdi: export BDI attributes in sysfs, Linus Torvalds, (Thu May 15, 12:54 pm)
Re: [BUG] mm: bdi: export BDI attributes in sysfs, Arthur Jones, (Thu May 15, 1:44 pm)
Re: [BUG] mm: bdi: export BDI attributes in sysfs, Arthur Jones, (Thu May 15, 3:05 pm)