aboutsummaryrefslogtreecommitdiffstats
path: root/arch/um/kernel/irq.c
diff options
context:
space:
mode:
authorJeff Dike <jdike@addtoit.com>2006-09-26 02:33:04 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-09-26 11:49:07 -0400
commit19bdf0409f25a85a45874a5a8da6f3e4edcf4a49 (patch)
tree82abcba44b8026b3dab0e6d26bdf3109bc6bb0cf /arch/um/kernel/irq.c
parent6edf428ed177e333863a8e5c37751a9ec176f241 (diff)
[PATCH] uml: SIGIO cleanups
- Various cleanups in the sigio code. - Removed explicit zero-initializations of a few structures. - Improved some error messages. - An API change - there was an asymmetry between reactivate_fd calling maybe_sigio_broken, which goes through all the machinery of figuring out if a file descriptor supports SIGIO and applying the workaround to it if not, and deactivate_fd, which just turns off the descriptor. This is changed so that only activate_fd calls maybe_sigio_broken, when the descriptor is first seen. reactivate_fd now calls add_sigio_fd, which is symmetric with ignore_sigio_fd. This removes a recursion which makes a critical section look more critical than it really was, obsoleting a big comment to that effect. This requires keeping track of all descriptors which are getting the SIGIO treatment, not just the ones being polled at any given moment, so that reactivate_fd, through add_sigio_fd, doesn't try to tell the SIGIO thread about descriptors it doesn't care about. Signed-off-by: Jeff Dike <jdike@addtoit.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/um/kernel/irq.c')
-rw-r--r--arch/um/kernel/irq.c34
1 files changed, 10 insertions, 24 deletions
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index 589c69a75043..ce7f233fc490 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -142,19 +142,6 @@ int activate_fd(int irq, int fd, int type, void *dev_id)
142 .events = events, 142 .events = events,
143 .current_events = 0 } ); 143 .current_events = 0 } );
144 144
145 /* Critical section - locked by a spinlock because this stuff can
146 * be changed from interrupt handlers. The stuff above is done
147 * outside the lock because it allocates memory.
148 */
149
150 /* Actually, it only looks like it can be called from interrupt
151 * context. The culprit is reactivate_fd, which calls
152 * maybe_sigio_broken, which calls write_sigio_workaround,
153 * which calls activate_fd. However, write_sigio_workaround should
154 * only be called once, at boot time. That would make it clear that
155 * this is called only from process context, and can be locked with
156 * a semaphore.
157 */
158 spin_lock_irqsave(&irq_lock, flags); 145 spin_lock_irqsave(&irq_lock, flags);
159 for (irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next) { 146 for (irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next) {
160 if ((irq_fd->fd == fd) && (irq_fd->type == type)) { 147 if ((irq_fd->fd == fd) && (irq_fd->type == type)) {
@@ -165,7 +152,6 @@ int activate_fd(int irq, int fd, int type, void *dev_id)
165 } 152 }
166 } 153 }
167 154
168 /*-------------*/
169 if (type == IRQ_WRITE) 155 if (type == IRQ_WRITE)
170 fd = -1; 156 fd = -1;
171 157
@@ -198,7 +184,6 @@ int activate_fd(int irq, int fd, int type, void *dev_id)
198 184
199 spin_lock_irqsave(&irq_lock, flags); 185 spin_lock_irqsave(&irq_lock, flags);
200 } 186 }
201 /*-------------*/
202 187
203 *last_irq_ptr = new_fd; 188 *last_irq_ptr = new_fd;
204 last_irq_ptr = &new_fd->next; 189 last_irq_ptr = &new_fd->next;
@@ -210,14 +195,14 @@ int activate_fd(int irq, int fd, int type, void *dev_id)
210 */ 195 */
211 maybe_sigio_broken(fd, (type == IRQ_READ)); 196 maybe_sigio_broken(fd, (type == IRQ_READ));
212 197
213 return(0); 198 return 0;
214 199
215 out_unlock: 200 out_unlock:
216 spin_unlock_irqrestore(&irq_lock, flags); 201 spin_unlock_irqrestore(&irq_lock, flags);
217 out_kfree: 202 out_kfree:
218 kfree(new_fd); 203 kfree(new_fd);
219 out: 204 out:
220 return(err); 205 return err;
221} 206}
222 207
223static void free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg) 208static void free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg)
@@ -302,10 +287,7 @@ void reactivate_fd(int fd, int irqnum)
302 os_set_pollfd(i, irq->fd); 287 os_set_pollfd(i, irq->fd);
303 spin_unlock_irqrestore(&irq_lock, flags); 288 spin_unlock_irqrestore(&irq_lock, flags);
304 289
305 /* This calls activate_fd, so it has to be outside the critical 290 add_sigio_fd(fd);
306 * section.
307 */
308 maybe_sigio_broken(fd, (irq->type == IRQ_READ));
309} 291}
310 292
311void deactivate_fd(int fd, int irqnum) 293void deactivate_fd(int fd, int irqnum)
@@ -316,11 +298,15 @@ void deactivate_fd(int fd, int irqnum)
316 298
317 spin_lock_irqsave(&irq_lock, flags); 299 spin_lock_irqsave(&irq_lock, flags);
318 irq = find_irq_by_fd(fd, irqnum, &i); 300 irq = find_irq_by_fd(fd, irqnum, &i);
319 if (irq == NULL) 301 if(irq == NULL){
320 goto out; 302 spin_unlock_irqrestore(&irq_lock, flags);
303 return;
304 }
305
321 os_set_pollfd(i, -1); 306 os_set_pollfd(i, -1);
322 out:
323 spin_unlock_irqrestore(&irq_lock, flags); 307 spin_unlock_irqrestore(&irq_lock, flags);
308
309 ignore_sigio_fd(fd);
324} 310}
325 311
326int deactivate_all_fds(void) 312int deactivate_all_fds(void)