and changed files
[powerpc.git] / kernel / relay.c
index ef923f6..4311101 100644 (file)
@@ -310,16 +310,13 @@ static struct rchan_callbacks default_channel_callbacks = {
 
 /**
  *     wakeup_readers - wake up readers waiting on a channel
- *     @work: work struct that contains the the channel buffer
+ *     @data: contains the channel buffer
  *
- *     This is the work function used to defer reader waking.  The
- *     reason waking is deferred is that calling directly from write
- *     causes problems if you're writing from say the scheduler.
+ *     This is the timer function used to defer reader waking.
  */
-static void wakeup_readers(struct work_struct *work)
+static void wakeup_readers(unsigned long data)
 {
-       struct rchan_buf *buf =
-               container_of(work, struct rchan_buf, wake_readers.work);
+       struct rchan_buf *buf = (struct rchan_buf *)data;
        wake_up_interruptible(&buf->read_wait);
 }
 
@@ -328,7 +325,7 @@ static void wakeup_readers(struct work_struct *work)
  *     @buf: the channel buffer
  *     @init: 1 if this is a first-time initialization
  *
- *     See relay_reset for description of effect.
+ *     See relay_reset() for description of effect.
  */
 static void __relay_reset(struct rchan_buf *buf, unsigned int init)
 {
@@ -337,11 +334,9 @@ static void __relay_reset(struct rchan_buf *buf, unsigned int init)
        if (init) {
                init_waitqueue_head(&buf->read_wait);
                kref_init(&buf->kref);
-               INIT_DELAYED_WORK(&buf->wake_readers, NULL);
-       } else {
-               cancel_delayed_work(&buf->wake_readers);
-               flush_scheduled_work();
-       }
+               setup_timer(&buf->timer, wakeup_readers, (unsigned long)buf);
+       } else
+               del_timer_sync(&buf->timer);
 
        buf->subbufs_produced = 0;
        buf->subbufs_consumed = 0;
@@ -364,7 +359,7 @@ static void __relay_reset(struct rchan_buf *buf, unsigned int init)
  *     and restarting the channel in its initial state.  The buffers
  *     are not freed, so any mappings are still in effect.
  *
- *     NOTE: Care should be taken that the channel isn't actually
+ *     NOTE. Care should be taken that the channel isn't actually
  *     being used by anything when this call is made.
  */
 void relay_reset(struct rchan *chan)
@@ -447,8 +442,7 @@ end:
 static void relay_close_buf(struct rchan_buf *buf)
 {
        buf->finalized = 1;
-       cancel_delayed_work(&buf->wake_readers);
-       flush_scheduled_work();
+       del_timer_sync(&buf->timer);
        kref_put(&buf->kref, relay_remove_buf);
 }
 
@@ -474,13 +468,12 @@ static void setup_callbacks(struct rchan *chan,
 }
 
 /**
- *
  *     relay_hotcpu_callback - CPU hotplug callback
  *     @nb: notifier block
  *     @action: hotplug action to take
  *     @hcpu: CPU number
  *
- *     Returns the success/failure of the operation. (NOTIFY_OK, NOTIFY_BAD)
+ *     Returns the success/failure of the operation. (%NOTIFY_OK, %NOTIFY_BAD)
  */
 static int __cpuinit relay_hotcpu_callback(struct notifier_block *nb,
                                unsigned long action,
@@ -491,6 +484,7 @@ static int __cpuinit relay_hotcpu_callback(struct notifier_block *nb,
 
        switch(action) {
        case CPU_UP_PREPARE:
+       case CPU_UP_PREPARE_FROZEN:
                mutex_lock(&relay_channels_mutex);
                list_for_each_entry(chan, &relay_channels, list) {
                        if (chan->buf[hotcpu])
@@ -507,6 +501,7 @@ static int __cpuinit relay_hotcpu_callback(struct notifier_block *nb,
                mutex_unlock(&relay_channels_mutex);
                break;
        case CPU_DEAD:
+       case CPU_DEAD_FROZEN:
                /* No need to flush the cpu : will be flushed upon
                 * final relay_flush() call. */
                break;
@@ -528,7 +523,7 @@ static int __cpuinit relay_hotcpu_callback(struct notifier_block *nb,
  *     Creates a channel buffer for each cpu using the sizes and
  *     attributes specified.  The created channel buffer files
  *     will be named base_filename0...base_filenameN-1.  File
- *     permissions will be S_IRUSR.
+ *     permissions will be %S_IRUSR.
  */
 struct rchan *relay_open(const char *base_filename,
                         struct dentry *parent,
@@ -609,11 +604,14 @@ size_t relay_switch_subbuf(struct rchan_buf *buf, size_t length)
                buf->dentry->d_inode->i_size += buf->chan->subbuf_size -
                        buf->padding[old_subbuf];
                smp_mb();
-               if (waitqueue_active(&buf->read_wait)) {
-                       PREPARE_DELAYED_WORK(&buf->wake_readers,
-                                            wakeup_readers);
-                       schedule_delayed_work(&buf->wake_readers, 1);
-               }
+               if (waitqueue_active(&buf->read_wait))
+                       /*
+                        * Calling wake_up_interruptible() from here
+                        * will deadlock if we happen to be logging
+                        * from the scheduler (trying to re-grab
+                        * rq->lock), so defer it.
+                        */
+                       __mod_timer(&buf->timer, jiffies + 1);
        }
 
        old = buf->data;
@@ -648,7 +646,7 @@ EXPORT_SYMBOL_GPL(relay_switch_subbuf);
  *     subbufs_consumed should be the number of sub-buffers newly consumed,
  *     not the total consumed.
  *
- *     NOTE: Kernel clients don't need to call this function if the channel
+ *     NOTE. Kernel clients don't need to call this function if the channel
  *     mode is 'overwrite'.
  */
 void relay_subbufs_consumed(struct rchan *chan,
@@ -749,7 +747,7 @@ static int relay_file_open(struct inode *inode, struct file *filp)
  *     @filp: the file
  *     @vma: the vma describing what to map
  *
- *     Calls upon relay_mmap_buf to map the file into user space.
+ *     Calls upon relay_mmap_buf() to map the file into user space.
  */
 static int relay_file_mmap(struct file *filp, struct vm_area_struct *vma)
 {
@@ -891,7 +889,7 @@ static size_t relay_file_read_subbuf_avail(size_t read_pos,
  *     @read_pos: file read position
  *     @buf: relay channel buffer
  *
- *     If the read_pos is in the middle of padding, return the
+ *     If the @read_pos is in the middle of padding, return the
  *     position of the first actually available byte, otherwise
  *     return the original value.
  */