direct-io.hg

view patches/linux-2.6.16.13/blktap-aio-16_03_06.patch @ 11522:1fae74cd3963

[POWERPC][XEN] Fix infinite loop caused by hdec storm

This was the cause of the periodic hang on secondary processors that has
been holding back the submission of the SMP patch.

Signed-off-by: Amos Waterland <apw@us.ibm.com>
Signed-off-by: Hollis Blanchard <hollisb@us.ibm.com>
author Jimi Xenidis <jimix@watson.ibm.com>
date Thu Sep 14 22:06:15 2006 -0400 (2006-09-14)
parents 2937703f0ed0
children
line source
1 diff -pruN ../pristine-linux-2.6.16-rc5/fs/aio.c ./fs/aio.c
2 --- ../pristine-linux-2.6.16-rc5/fs/aio.c 2006-03-14 14:10:10.827401387 +0000
3 +++ ./fs/aio.c 2006-03-16 09:57:53.898316582 +0000
4 @@ -34,6 +34,11 @@
5 #include <asm/uaccess.h>
6 #include <asm/mmu_context.h>
8 +#ifdef CONFIG_EPOLL
9 +#include <linux/poll.h>
10 +#include <linux/eventpoll.h>
11 +#endif
12 +
13 #if DEBUG > 1
14 #define dprintk printk
15 #else
16 @@ -1016,6 +1021,10 @@ put_rq:
17 if (waitqueue_active(&ctx->wait))
18 wake_up(&ctx->wait);
20 +#ifdef CONFIG_EPOLL
21 + if (ctx->file && waitqueue_active(&ctx->poll_wait))
22 + wake_up(&ctx->poll_wait);
23 +#endif
24 if (ret)
25 put_ioctx(ctx);
27 @@ -1025,6 +1034,8 @@ put_rq:
28 /* aio_read_evt
29 * Pull an event off of the ioctx's event ring. Returns the number of
30 * events fetched (0 or 1 ;-)
31 + * If ent parameter is 0, just returns the number of events that would
32 + * be fetched.
33 * FIXME: make this use cmpxchg.
34 * TODO: make the ringbuffer user mmap()able (requires FIXME).
35 */
36 @@ -1047,13 +1058,18 @@ static int aio_read_evt(struct kioctx *i
38 head = ring->head % info->nr;
39 if (head != ring->tail) {
40 - struct io_event *evp = aio_ring_event(info, head, KM_USER1);
41 - *ent = *evp;
42 - head = (head + 1) % info->nr;
43 - smp_mb(); /* finish reading the event before updatng the head */
44 - ring->head = head;
45 - ret = 1;
46 - put_aio_ring_event(evp, KM_USER1);
47 + if (ent) { /* event requested */
48 + struct io_event *evp =
49 + aio_ring_event(info, head, KM_USER1);
50 + *ent = *evp;
51 + head = (head + 1) % info->nr;
52 + /* finish reading the event before updatng the head */
53 + smp_mb();
54 + ring->head = head;
55 + ret = 1;
56 + put_aio_ring_event(evp, KM_USER1);
57 + } else /* only need to know availability */
58 + ret = 1;
59 }
60 spin_unlock(&info->ring_lock);
62 @@ -1236,9 +1252,78 @@ static void io_destroy(struct kioctx *io
64 aio_cancel_all(ioctx);
65 wait_for_all_aios(ioctx);
66 +#ifdef CONFIG_EPOLL
67 + /* forget the poll file, but it's up to the user to close it */
68 + if (ioctx->file) {
69 + ioctx->file->private_data = 0;
70 + ioctx->file = 0;
71 + }
72 +#endif
73 put_ioctx(ioctx); /* once for the lookup */
74 }
76 +#ifdef CONFIG_EPOLL
77 +
78 +static int aio_queue_fd_close(struct inode *inode, struct file *file)
79 +{
80 + struct kioctx *ioctx = file->private_data;
81 + if (ioctx) {
82 + file->private_data = 0;
83 + spin_lock_irq(&ioctx->ctx_lock);
84 + ioctx->file = 0;
85 + spin_unlock_irq(&ioctx->ctx_lock);
86 + }
87 + return 0;
88 +}
89 +
90 +static unsigned int aio_queue_fd_poll(struct file *file, poll_table *wait)
91 +{ unsigned int pollflags = 0;
92 + struct kioctx *ioctx = file->private_data;
93 +
94 + if (ioctx) {
95 +
96 + spin_lock_irq(&ioctx->ctx_lock);
97 + /* Insert inside our poll wait queue */
98 + poll_wait(file, &ioctx->poll_wait, wait);
99 +
100 + /* Check our condition */
101 + if (aio_read_evt(ioctx, 0))
102 + pollflags = POLLIN | POLLRDNORM;
103 + spin_unlock_irq(&ioctx->ctx_lock);
104 + }
105 +
106 + return pollflags;
107 +}
108 +
109 +static struct file_operations aioq_fops = {
110 + .release = aio_queue_fd_close,
111 + .poll = aio_queue_fd_poll
112 +};
113 +
114 +/* make_aio_fd:
115 + * Create a file descriptor that can be used to poll the event queue.
116 + * Based and piggybacked on the excellent epoll code.
117 + */
118 +
119 +static int make_aio_fd(struct kioctx *ioctx)
120 +{
121 + int error, fd;
122 + struct inode *inode;
123 + struct file *file;
124 +
125 + error = ep_getfd(&fd, &inode, &file, NULL, &aioq_fops);
126 + if (error)
127 + return error;
128 +
129 + /* associate the file with the IO context */
130 + file->private_data = ioctx;
131 + ioctx->file = file;
132 + init_waitqueue_head(&ioctx->poll_wait);
133 + return fd;
134 +}
135 +#endif
136 +
137 +
138 /* sys_io_setup:
139 * Create an aio_context capable of receiving at least nr_events.
140 * ctxp must not point to an aio_context that already exists, and
141 @@ -1251,18 +1336,30 @@ static void io_destroy(struct kioctx *io
142 * resources are available. May fail with -EFAULT if an invalid
143 * pointer is passed for ctxp. Will fail with -ENOSYS if not
144 * implemented.
145 + *
146 + * To request a selectable fd, the user context has to be initialized
147 + * to 1, instead of 0, and the return value is the fd.
148 + * This keeps the system call compatible, since a non-zero value
149 + * was not allowed so far.
150 */
151 asmlinkage long sys_io_setup(unsigned nr_events, aio_context_t __user *ctxp)
152 {
153 struct kioctx *ioctx = NULL;
154 unsigned long ctx;
155 long ret;
156 + int make_fd = 0;
158 ret = get_user(ctx, ctxp);
159 if (unlikely(ret))
160 goto out;
162 ret = -EINVAL;
163 +#ifdef CONFIG_EPOLL
164 + if (ctx == 1) {
165 + make_fd = 1;
166 + ctx = 0;
167 + }
168 +#endif
169 if (unlikely(ctx || nr_events == 0)) {
170 pr_debug("EINVAL: io_setup: ctx %lu nr_events %u\n",
171 ctx, nr_events);
172 @@ -1273,8 +1370,12 @@ asmlinkage long sys_io_setup(unsigned nr
173 ret = PTR_ERR(ioctx);
174 if (!IS_ERR(ioctx)) {
175 ret = put_user(ioctx->user_id, ctxp);
176 - if (!ret)
177 - return 0;
178 +#ifdef CONFIG_EPOLL
179 + if (make_fd && ret >= 0)
180 + ret = make_aio_fd(ioctx);
181 +#endif
182 + if (ret >= 0)
183 + return ret;
185 get_ioctx(ioctx); /* io_destroy() expects us to hold a ref */
186 io_destroy(ioctx);
188 diff -pruN ../pristine-linux-2.6.16-rc5/fs/eventpoll.c ./fs/eventpoll.c
189 --- ../pristine-linux-2.6.16-rc5/fs/eventpoll.c 2006-01-03 03:21:10.000000000 +0000
190 +++ ./fs/eventpoll.c 2006-03-16 10:04:35.469956167 +0000
191 @@ -235,8 +235,6 @@ struct ep_pqueue {
193 static void ep_poll_safewake_init(struct poll_safewake *psw);
194 static void ep_poll_safewake(struct poll_safewake *psw, wait_queue_head_t *wq);
195 -static int ep_getfd(int *efd, struct inode **einode, struct file **efile,
196 - struct eventpoll *ep);
197 static int ep_alloc(struct eventpoll **pep);
198 static void ep_free(struct eventpoll *ep);
199 static struct epitem *ep_find(struct eventpoll *ep, struct file *file, int fd);
200 @@ -266,7 +264,7 @@ static int ep_events_transfer(struct eve
201 static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events,
202 int maxevents, long timeout);
203 static int eventpollfs_delete_dentry(struct dentry *dentry);
204 -static struct inode *ep_eventpoll_inode(void);
205 +static struct inode *ep_eventpoll_inode(struct file_operations *fops);
206 static struct super_block *eventpollfs_get_sb(struct file_system_type *fs_type,
207 int flags, const char *dev_name,
208 void *data);
209 @@ -525,7 +523,7 @@ asmlinkage long sys_epoll_create(int siz
210 * Creates all the items needed to setup an eventpoll file. That is,
211 * a file structure, and inode and a free file descriptor.
212 */
213 - error = ep_getfd(&fd, &inode, &file, ep);
214 + error = ep_getfd(&fd, &inode, &file, ep, &eventpoll_fops);
215 if (error)
216 goto eexit_2;
218 @@ -710,8 +708,8 @@ eexit_1:
219 /*
220 * Creates the file descriptor to be used by the epoll interface.
221 */
222 -static int ep_getfd(int *efd, struct inode **einode, struct file **efile,
223 - struct eventpoll *ep)
224 +int ep_getfd(int *efd, struct inode **einode, struct file **efile,
225 + struct eventpoll *ep, struct file_operations *fops)
226 {
227 struct qstr this;
228 char name[32];
229 @@ -727,7 +725,7 @@ static int ep_getfd(int *efd, struct ino
230 goto eexit_1;
232 /* Allocates an inode from the eventpoll file system */
233 - inode = ep_eventpoll_inode();
234 + inode = ep_eventpoll_inode(fops);
235 error = PTR_ERR(inode);
236 if (IS_ERR(inode))
237 goto eexit_2;
238 @@ -758,7 +756,7 @@ static int ep_getfd(int *efd, struct ino
240 file->f_pos = 0;
241 file->f_flags = O_RDONLY;
242 - file->f_op = &eventpoll_fops;
243 + file->f_op = fops;
244 file->f_mode = FMODE_READ;
245 file->f_version = 0;
246 file->private_data = ep;
247 @@ -1574,7 +1572,7 @@ static int eventpollfs_delete_dentry(str
248 }
251 -static struct inode *ep_eventpoll_inode(void)
252 +static struct inode *ep_eventpoll_inode(struct file_operations *fops)
253 {
254 int error = -ENOMEM;
255 struct inode *inode = new_inode(eventpoll_mnt->mnt_sb);
256 @@ -1582,7 +1580,7 @@ static struct inode *ep_eventpoll_inode(
257 if (!inode)
258 goto eexit_1;
260 - inode->i_fop = &eventpoll_fops;
261 + inode->i_fop = fops;
263 /*
264 * Mark the inode dirty from the very beginning,
266 diff -pruN ../pristine-linux-2.6.16-rc5/include/linux/aio.h ./include/linux/aio.h
267 --- ../pristine-linux-2.6.16-rc5/include/linux/aio.h 2006-03-14 14:10:21.597916731 +0000
268 +++ ./include/linux/aio.h 2006-03-16 10:05:39.848833028 +0000
269 @@ -191,6 +191,11 @@ struct kioctx {
270 struct aio_ring_info ring_info;
272 struct work_struct wq;
273 +#ifdef CONFIG_EPOLL
274 + // poll integration
275 + wait_queue_head_t poll_wait;
276 + struct file *file;
277 +#endif
278 };
280 /* prototypes */
282 diff -pruN ../pristine-linux-2.6.16-rc5/include/linux/eventpoll.h ./include/linux/eventpoll.h
283 --- ../pristine-linux-2.6.16-rc5/include/linux/eventpoll.h 2006-01-03 03:21:10.000000000 +0000
284 +++ ./include/linux/eventpoll.h 2006-03-16 10:08:51.577809317 +0000
285 @@ -86,6 +86,12 @@ static inline void eventpoll_release(str
286 }
289 +/*
290 + * called by aio code to create fd that can poll the aio event queueQ
291 + */
292 +struct eventpoll;
293 +int ep_getfd(int *efd, struct inode **einode, struct file **efile,
294 + struct eventpoll *ep, struct file_operations *fops);
295 #else
297 static inline void eventpoll_init_file(struct file *file) {}