diff options
author | Shawn Bohrer <shawn.bohrer@gmail.com> | 2011-03-22 19:34:47 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-03-22 20:44:15 -0400 |
commit | f4d93ad74c18143abd3067ca3c8ffba7d00addf4 (patch) | |
tree | 470d7e53e696c9ff2f8e62caabb50e365ac9ca8c /fs/eventpoll.c | |
parent | 3fb0e584a68cd1c5085e69be441f2ad032aaee72 (diff) |
epoll: fix compiler warning and optimize the non-blocking path
Add a comment to ep_poll(), rename labels a bit clearly, fix a warning of
unused variable from gcc and optimize the non-blocking path a little.
Hinted-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Davide Libenzi <davidel@xmailserver.org>
hannes@cmpxchg.org:
: The non-blocking ep_poll path optimization introduced skipping over the
: return value setup.
:
: Initialize it properly, my userspace gets upset by epoll_wait() returning
: random things.
:
: In addition, remove the reinitialization at the fetch_events label, the
: return value is garuanteed to be zero when execution reaches there.
[hannes@cmpxchg.org: fix initialization]
Signed-off-by: Johannes Weiner <hannes@cmpxchg.org>
Cc: Shawn Bohrer <shawn.bohrer@gmail.com>
Acked-by: Davide Libenzi <davidel@xmailserver.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'fs/eventpoll.c')
-rw-r--r-- | fs/eventpoll.c | 33 |
1 files changed, 28 insertions, 5 deletions
diff --git a/fs/eventpoll.c b/fs/eventpoll.c index 57298d092f56..ed38801b57a7 100644 --- a/fs/eventpoll.c +++ b/fs/eventpoll.c | |||
@@ -1148,12 +1148,29 @@ static inline struct timespec ep_set_mstimeout(long ms) | |||
1148 | return timespec_add_safe(now, ts); | 1148 | return timespec_add_safe(now, ts); |
1149 | } | 1149 | } |
1150 | 1150 | ||
1151 | /** | ||
1152 | * ep_poll - Retrieves ready events, and delivers them to the caller supplied | ||
1153 | * event buffer. | ||
1154 | * | ||
1155 | * @ep: Pointer to the eventpoll context. | ||
1156 | * @events: Pointer to the userspace buffer where the ready events should be | ||
1157 | * stored. | ||
1158 | * @maxevents: Size (in terms of number of events) of the caller event buffer. | ||
1159 | * @timeout: Maximum timeout for the ready events fetch operation, in | ||
1160 | * milliseconds. If the @timeout is zero, the function will not block, | ||
1161 | * while if the @timeout is less than zero, the function will block | ||
1162 | * until at least one event has been retrieved (or an error | ||
1163 | * occurred). | ||
1164 | * | ||
1165 | * Returns: Returns the number of ready events which have been fetched, or an | ||
1166 | * error code, in case of error. | ||
1167 | */ | ||
1151 | static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events, | 1168 | static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events, |
1152 | int maxevents, long timeout) | 1169 | int maxevents, long timeout) |
1153 | { | 1170 | { |
1154 | int res, eavail, timed_out = 0; | 1171 | int res = 0, eavail, timed_out = 0; |
1155 | unsigned long flags; | 1172 | unsigned long flags; |
1156 | long slack; | 1173 | long slack = 0; |
1157 | wait_queue_t wait; | 1174 | wait_queue_t wait; |
1158 | ktime_t expires, *to = NULL; | 1175 | ktime_t expires, *to = NULL; |
1159 | 1176 | ||
@@ -1164,13 +1181,18 @@ static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events, | |||
1164 | to = &expires; | 1181 | to = &expires; |
1165 | *to = timespec_to_ktime(end_time); | 1182 | *to = timespec_to_ktime(end_time); |
1166 | } else if (timeout == 0) { | 1183 | } else if (timeout == 0) { |
1184 | /* | ||
1185 | * Avoid the unnecessary trip to the wait queue loop, if the | ||
1186 | * caller specified a non blocking operation. | ||
1187 | */ | ||
1167 | timed_out = 1; | 1188 | timed_out = 1; |
1189 | spin_lock_irqsave(&ep->lock, flags); | ||
1190 | goto check_events; | ||
1168 | } | 1191 | } |
1169 | 1192 | ||
1170 | retry: | 1193 | fetch_events: |
1171 | spin_lock_irqsave(&ep->lock, flags); | 1194 | spin_lock_irqsave(&ep->lock, flags); |
1172 | 1195 | ||
1173 | res = 0; | ||
1174 | if (!ep_events_available(ep)) { | 1196 | if (!ep_events_available(ep)) { |
1175 | /* | 1197 | /* |
1176 | * We don't have any available event to return to the caller. | 1198 | * We don't have any available event to return to the caller. |
@@ -1204,6 +1226,7 @@ retry: | |||
1204 | 1226 | ||
1205 | set_current_state(TASK_RUNNING); | 1227 | set_current_state(TASK_RUNNING); |
1206 | } | 1228 | } |
1229 | check_events: | ||
1207 | /* Is it worth to try to dig for events ? */ | 1230 | /* Is it worth to try to dig for events ? */ |
1208 | eavail = ep_events_available(ep); | 1231 | eavail = ep_events_available(ep); |
1209 | 1232 | ||
@@ -1216,7 +1239,7 @@ retry: | |||
1216 | */ | 1239 | */ |
1217 | if (!res && eavail && | 1240 | if (!res && eavail && |
1218 | !(res = ep_send_events(ep, events, maxevents)) && !timed_out) | 1241 | !(res = ep_send_events(ep, events, maxevents)) && !timed_out) |
1219 | goto retry; | 1242 | goto fetch_events; |
1220 | 1243 | ||
1221 | return res; | 1244 | return res; |
1222 | } | 1245 | } |