[LinuxPPS] [PATCH] Bug on sleeping during invalid context

Rodolfo Giometti giometti at enneenne.com
Tue Jan 30 16:24:17 CET 2007


Please, try out this patch ASAP who should remove a kernel bug during
PPS source registering/unregistering otherwise I have to delay sending
LinuxPPS patch to the LKML!

Thanks for your help,

Rodolfo

-- 

GNU/Linux Solutions                  e-mail:    giometti at enneenne.com
Linux Device Driver                             giometti at gnudd.com
Embedded Systems                     		giometti at linux.it
UNIX programming                     phone:     +39 349 2432127
-------------- next part --------------
diff --git a/drivers/pps/kapi.c b/drivers/pps/kapi.c
index 2487778..8d47dd1 100644
--- a/drivers/pps/kapi.c
+++ b/drivers/pps/kapi.c
@@ -50,7 +50,7 @@ static void linuxpps_add_offset(struct timespec *ts, struct timespec *offset)
 
 static inline int __linuxpps_register_source(struct linuxpps_source_info_s *info, int default_params, int try_id)
 {
-	int i, ret;
+	int i;
 
 	if (try_id >= 0) {
 		if (__linuxpps_is_allocated(try_id)) {
@@ -90,30 +90,34 @@ static inline int __linuxpps_register_source(struct linuxpps_source_info_s *info
 	linuxpps_source[i].params.mode = default_params;
 	init_waitqueue_head(&linuxpps_source[i].queue);
 
-	ret = linuxpps_sysfs_create_source_entry(info, i);
-	if (ret < 0)
-		err("unable to create sysfs entry for source %d", i);
-
-	ret = linuxpps_procfs_create_source_entry(info, i);
-	if (ret < 0)
-		err("unable to create procfs entry for source %d", i);
-
 	return i;
 }
 
 int linuxpps_register_source(struct linuxpps_source_info_s *info, int default_params, int try_id)
 {
 	unsigned long flags;
-	int ret;
+	int i, ret;
 
 	spin_lock_irqsave(&linuxpps_lock, flags);
 	ret = __linuxpps_register_source(info, default_params, try_id);
 	spin_unlock_irqrestore(&linuxpps_lock, flags);
 
-	return ret;
+	if (ret)
+		return ret;
+	i = ret;
+
+	ret = linuxpps_sysfs_create_source_entry(info, i);
+	if (ret < 0)
+		err("unable to create sysfs entry for source %d", i);
+
+	ret = linuxpps_procfs_create_source_entry(info, i);
+	if (ret < 0)
+		err("unable to create procfs entry for source %d", i);
+
+	return i;
 }
 
-static inline void __linuxpps_unregister_source(struct linuxpps_source_info_s *info)
+static inline int __linuxpps_unregister_source(struct linuxpps_source_info_s *info)
 {  
 	int i;
 
@@ -123,22 +127,30 @@ static inline void __linuxpps_unregister_source(struct linuxpps_source_info_s *i
 
 	if (i >= LINUXPPS_MAX_SOURCES) {
 		err("warning! Try to unregister an unknow PPS source");
-		return;
+		return -EINVAL;
 	}
 
 	/* Deallocate the PPS source */
-	linuxpps_sysfs_remove_source_entry(info, i);
-	linuxpps_procfs_remove_source_entry(info, i);
 	linuxpps_source[i].info = NULL; 
+
+	return i;
 } 
 
 void linuxpps_unregister_source(struct linuxpps_source_info_s *info)
 {
 	unsigned long flags;
+	int i, ret;
 
 	spin_lock_irqsave(&linuxpps_lock, flags);
-	__linuxpps_unregister_source(info);
+	ret = __linuxpps_unregister_source(info);
 	spin_unlock_irqrestore(&linuxpps_lock, flags);
+
+	if (ret)
+		return;
+	i = ret;
+
+	linuxpps_sysfs_remove_source_entry(info, i);
+	linuxpps_procfs_remove_source_entry(info, i);
 }
 
 void linuxpps_event(int source, int event, void *data)


More information about the LinuxPPS mailing list