[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