diff options
author | Jeff Dike <jdike@addtoit.com> | 2006-09-26 02:33:04 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-09-26 11:49:07 -0400 |
commit | 19bdf0409f25a85a45874a5a8da6f3e4edcf4a49 (patch) | |
tree | 82abcba44b8026b3dab0e6d26bdf3109bc6bb0cf /arch/um/kernel/irq.c | |
parent | 6edf428ed177e333863a8e5c37751a9ec176f241 (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.c | 34 |
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 | ||
223 | static void free_irq_by_cb(int (*test)(struct irq_fd *, void *), void *arg) | 208 | static 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 | ||
311 | void deactivate_fd(int fd, int irqnum) | 293 | void 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 | ||
326 | int deactivate_all_fds(void) | 312 | int deactivate_all_fds(void) |