Merge branch 'akpm-current/current'
[deliverable/linux.git] / include / linux / relay.h
index d7c8359693c6e19cdf57c52316f2e223581f14b2..ab0c59e947104e053996fb4141306f79744e92b6 100644 (file)
@@ -19,6 +19,8 @@
 #include <linux/fs.h>
 #include <linux/poll.h>
 #include <linux/kref.h>
+#include <linux/percpu.h>
+#include <linux/irq_work.h>
 
 /*
  * Tracks changes to rchan/rchan_buf structs
@@ -37,7 +39,7 @@ struct rchan_buf
        size_t subbufs_consumed;        /* count of sub-buffers consumed */
        struct rchan *chan;             /* associated channel */
        wait_queue_head_t read_wait;    /* reader wait queue */
-       struct timer_list timer;        /* reader wake-up timer */
+       struct irq_work wakeup_work;    /* reader wakeup */
        struct dentry *dentry;          /* channel file dentry */
        struct kref kref;               /* channel buffer refcount */
        struct page **page_array;       /* array of current buffer pages */
@@ -63,7 +65,7 @@ struct rchan
        struct kref kref;               /* channel refcount */
        void *private_data;             /* for user-defined data */
        size_t last_toobig;             /* tried to log event > subbuf size */
-       struct rchan_buf *buf[NR_CPUS]; /* per-cpu channel buffers */
+       struct rchan_buf ** __percpu buf; /* per-cpu channel buffers */
        int is_global;                  /* One global buffer ? */
        struct list_head list;          /* for channel list */
        struct dentry *parent;          /* parent dentry passed to open */
@@ -204,7 +206,7 @@ static inline void relay_write(struct rchan *chan,
        struct rchan_buf *buf;
 
        local_irq_save(flags);
-       buf = chan->buf[smp_processor_id()];
+       buf = *this_cpu_ptr(chan->buf);
        if (unlikely(buf->offset + length > chan->subbuf_size))
                length = relay_switch_subbuf(buf, length);
        memcpy(buf->data + buf->offset, data, length);
@@ -230,12 +232,12 @@ static inline void __relay_write(struct rchan *chan,
 {
        struct rchan_buf *buf;
 
-       buf = chan->buf[get_cpu()];
+       buf = *get_cpu_ptr(chan->buf);
        if (unlikely(buf->offset + length > buf->chan->subbuf_size))
                length = relay_switch_subbuf(buf, length);
        memcpy(buf->data + buf->offset, data, length);
        buf->offset += length;
-       put_cpu();
+       put_cpu_ptr(chan->buf);
 }
 
 /**
@@ -251,17 +253,19 @@ static inline void __relay_write(struct rchan *chan,
  */
 static inline void *relay_reserve(struct rchan *chan, size_t length)
 {
-       void *reserved;
-       struct rchan_buf *buf = chan->buf[smp_processor_id()];
+       void *reserved = NULL;
+       struct rchan_buf *buf = *get_cpu_ptr(chan->buf);
 
        if (unlikely(buf->offset + length > buf->chan->subbuf_size)) {
                length = relay_switch_subbuf(buf, length);
                if (!length)
-                       return NULL;
+                       goto end;
        }
        reserved = buf->data + buf->offset;
        buf->offset += length;
 
+end:
+       put_cpu_ptr(chan->buf);
        return reserved;
 }
 
@@ -285,5 +289,11 @@ static inline void subbuf_start_reserve(struct rchan_buf *buf,
  */
 extern const struct file_operations relay_file_operations;
 
+#ifdef CONFIG_RELAY
+int relay_prepare_cpu(unsigned int cpu);
+#else
+#define relay_prepare_cpu     NULL
+#endif
+
 #endif /* _LINUX_RELAY_H */
 
This page took 0.037882 seconds and 5 git commands to generate.