aboutsummaryrefslogtreecommitdiffstats
path: root/fs/eventpoll.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/eventpoll.c')
-rw-r--r--fs/eventpoll.c38
1 files changed, 21 insertions, 17 deletions
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index 3817149919cb..8cf07242067d 100644
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -77,9 +77,6 @@
77/* Maximum number of nesting allowed inside epoll sets */ 77/* Maximum number of nesting allowed inside epoll sets */
78#define EP_MAX_NESTS 4 78#define EP_MAX_NESTS 4
79 79
80/* Maximum msec timeout value storeable in a long int */
81#define EP_MAX_MSTIMEO min(1000ULL * MAX_SCHEDULE_TIMEOUT / HZ, (LONG_MAX - 999ULL) / HZ)
82
83#define EP_MAX_EVENTS (INT_MAX / sizeof(struct epoll_event)) 80#define EP_MAX_EVENTS (INT_MAX / sizeof(struct epoll_event))
84 81
85#define EP_UNACTIVE_PTR ((void *) -1L) 82#define EP_UNACTIVE_PTR ((void *) -1L)
@@ -674,7 +671,8 @@ static unsigned int ep_eventpoll_poll(struct file *file, poll_table *wait)
674/* File callbacks that implement the eventpoll file behaviour */ 671/* File callbacks that implement the eventpoll file behaviour */
675static const struct file_operations eventpoll_fops = { 672static const struct file_operations eventpoll_fops = {
676 .release = ep_eventpoll_release, 673 .release = ep_eventpoll_release,
677 .poll = ep_eventpoll_poll 674 .poll = ep_eventpoll_poll,
675 .llseek = noop_llseek,
678}; 676};
679 677
680/* Fast test to see if the file is an evenpoll file */ 678/* Fast test to see if the file is an evenpoll file */
@@ -1116,18 +1114,22 @@ static int ep_send_events(struct eventpoll *ep,
1116static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events, 1114static int ep_poll(struct eventpoll *ep, struct epoll_event __user *events,
1117 int maxevents, long timeout) 1115 int maxevents, long timeout)
1118{ 1116{
1119 int res, eavail; 1117 int res, eavail, timed_out = 0;
1120 unsigned long flags; 1118 unsigned long flags;
1121 long jtimeout; 1119 long slack;
1122 wait_queue_t wait; 1120 wait_queue_t wait;
1123 1121 struct timespec end_time;
1124 /* 1122 ktime_t expires, *to = NULL;
1125 * Calculate the timeout by checking for the "infinite" value (-1) 1123
1126 * and the overflow condition. The passed timeout is in milliseconds, 1124 if (timeout > 0) {
1127 * that why (t * HZ) / 1000. 1125 ktime_get_ts(&end_time);
1128 */ 1126 timespec_add_ns(&end_time, (u64)timeout * NSEC_PER_MSEC);
1129 jtimeout = (timeout < 0 || timeout >= EP_MAX_MSTIMEO) ? 1127 slack = select_estimate_accuracy(&end_time);
1130 MAX_SCHEDULE_TIMEOUT : (timeout * HZ + 999) / 1000; 1128 to = &expires;
1129 *to = timespec_to_ktime(end_time);
1130 } else if (timeout == 0) {
1131 timed_out = 1;
1132 }
1131 1133
1132retry: 1134retry:
1133 spin_lock_irqsave(&ep->lock, flags); 1135 spin_lock_irqsave(&ep->lock, flags);
@@ -1149,7 +1151,7 @@ retry:
1149 * to TASK_INTERRUPTIBLE before doing the checks. 1151 * to TASK_INTERRUPTIBLE before doing the checks.
1150 */ 1152 */
1151 set_current_state(TASK_INTERRUPTIBLE); 1153 set_current_state(TASK_INTERRUPTIBLE);
1152 if (!list_empty(&ep->rdllist) || !jtimeout) 1154 if (!list_empty(&ep->rdllist) || timed_out)
1153 break; 1155 break;
1154 if (signal_pending(current)) { 1156 if (signal_pending(current)) {
1155 res = -EINTR; 1157 res = -EINTR;
@@ -1157,7 +1159,9 @@ retry:
1157 } 1159 }
1158 1160
1159 spin_unlock_irqrestore(&ep->lock, flags); 1161 spin_unlock_irqrestore(&ep->lock, flags);
1160 jtimeout = schedule_timeout(jtimeout); 1162 if (!schedule_hrtimeout_range(to, slack, HRTIMER_MODE_ABS))
1163 timed_out = 1;
1164
1161 spin_lock_irqsave(&ep->lock, flags); 1165 spin_lock_irqsave(&ep->lock, flags);
1162 } 1166 }
1163 __remove_wait_queue(&ep->wq, &wait); 1167 __remove_wait_queue(&ep->wq, &wait);
@@ -1175,7 +1179,7 @@ retry:
1175 * more luck. 1179 * more luck.
1176 */ 1180 */
1177 if (!res && eavail && 1181 if (!res && eavail &&
1178 !(res = ep_send_events(ep, events, maxevents)) && jtimeout) 1182 !(res = ep_send_events(ep, events, maxevents)) && !timed_out)
1179 goto retry; 1183 goto retry;
1180 1184
1181 return res; 1185 return res;