diff options
| author | Thomas Gleixner <tglx@linutronix.de> | 2013-07-12 06:34:42 -0400 |
|---|---|---|
| committer | Thomas Gleixner <tglx@linutronix.de> | 2013-07-12 06:34:42 -0400 |
| commit | f2006e27396f55276f24434f56e208d86e7f9908 (patch) | |
| tree | 71896db916d33888b4286f80117d3cac0da40e6d /fs/select.c | |
| parent | e399eb56a6110e13f97e644658648602e2b08de7 (diff) | |
| parent | 9903883f1dd6e86f286b7bfa6e4b423f98c1cd9e (diff) | |
Merge branch 'linus' into timers/urgent
Get upstream changes so we can apply fixes against them
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'fs/select.c')
| -rw-r--r-- | fs/select.c | 66 |
1 files changed, 60 insertions, 6 deletions
diff --git a/fs/select.c b/fs/select.c index 8c1c96c27062..f9f49c40cfd4 100644 --- a/fs/select.c +++ b/fs/select.c | |||
| @@ -27,6 +27,8 @@ | |||
| 27 | #include <linux/rcupdate.h> | 27 | #include <linux/rcupdate.h> |
| 28 | #include <linux/hrtimer.h> | 28 | #include <linux/hrtimer.h> |
| 29 | #include <linux/sched/rt.h> | 29 | #include <linux/sched/rt.h> |
| 30 | #include <linux/freezer.h> | ||
| 31 | #include <net/ll_poll.h> | ||
| 30 | 32 | ||
| 31 | #include <asm/uaccess.h> | 33 | #include <asm/uaccess.h> |
| 32 | 34 | ||
| @@ -236,7 +238,8 @@ int poll_schedule_timeout(struct poll_wqueues *pwq, int state, | |||
| 236 | 238 | ||
| 237 | set_current_state(state); | 239 | set_current_state(state); |
| 238 | if (!pwq->triggered) | 240 | if (!pwq->triggered) |
| 239 | rc = schedule_hrtimeout_range(expires, slack, HRTIMER_MODE_ABS); | 241 | rc = freezable_schedule_hrtimeout_range(expires, slack, |
| 242 | HRTIMER_MODE_ABS); | ||
| 240 | __set_current_state(TASK_RUNNING); | 243 | __set_current_state(TASK_RUNNING); |
| 241 | 244 | ||
| 242 | /* | 245 | /* |
| @@ -384,9 +387,10 @@ get_max: | |||
| 384 | #define POLLEX_SET (POLLPRI) | 387 | #define POLLEX_SET (POLLPRI) |
| 385 | 388 | ||
| 386 | static inline void wait_key_set(poll_table *wait, unsigned long in, | 389 | static inline void wait_key_set(poll_table *wait, unsigned long in, |
| 387 | unsigned long out, unsigned long bit) | 390 | unsigned long out, unsigned long bit, |
| 391 | unsigned int ll_flag) | ||
| 388 | { | 392 | { |
| 389 | wait->_key = POLLEX_SET; | 393 | wait->_key = POLLEX_SET | ll_flag; |
| 390 | if (in & bit) | 394 | if (in & bit) |
| 391 | wait->_key |= POLLIN_SET; | 395 | wait->_key |= POLLIN_SET; |
| 392 | if (out & bit) | 396 | if (out & bit) |
| @@ -400,6 +404,8 @@ int do_select(int n, fd_set_bits *fds, struct timespec *end_time) | |||
| 400 | poll_table *wait; | 404 | poll_table *wait; |
| 401 | int retval, i, timed_out = 0; | 405 | int retval, i, timed_out = 0; |
| 402 | unsigned long slack = 0; | 406 | unsigned long slack = 0; |
| 407 | unsigned int busy_flag = net_busy_loop_on() ? POLL_BUSY_LOOP : 0; | ||
| 408 | unsigned long busy_end = 0; | ||
| 403 | 409 | ||
| 404 | rcu_read_lock(); | 410 | rcu_read_lock(); |
| 405 | retval = max_select_fd(n, fds); | 411 | retval = max_select_fd(n, fds); |
| @@ -422,6 +428,7 @@ int do_select(int n, fd_set_bits *fds, struct timespec *end_time) | |||
| 422 | retval = 0; | 428 | retval = 0; |
| 423 | for (;;) { | 429 | for (;;) { |
| 424 | unsigned long *rinp, *routp, *rexp, *inp, *outp, *exp; | 430 | unsigned long *rinp, *routp, *rexp, *inp, *outp, *exp; |
| 431 | bool can_busy_loop = false; | ||
| 425 | 432 | ||
| 426 | inp = fds->in; outp = fds->out; exp = fds->ex; | 433 | inp = fds->in; outp = fds->out; exp = fds->ex; |
| 427 | rinp = fds->res_in; routp = fds->res_out; rexp = fds->res_ex; | 434 | rinp = fds->res_in; routp = fds->res_out; rexp = fds->res_ex; |
| @@ -449,7 +456,8 @@ int do_select(int n, fd_set_bits *fds, struct timespec *end_time) | |||
| 449 | f_op = f.file->f_op; | 456 | f_op = f.file->f_op; |
| 450 | mask = DEFAULT_POLLMASK; | 457 | mask = DEFAULT_POLLMASK; |
| 451 | if (f_op && f_op->poll) { | 458 | if (f_op && f_op->poll) { |
| 452 | wait_key_set(wait, in, out, bit); | 459 | wait_key_set(wait, in, out, |
| 460 | bit, busy_flag); | ||
| 453 | mask = (*f_op->poll)(f.file, wait); | 461 | mask = (*f_op->poll)(f.file, wait); |
| 454 | } | 462 | } |
| 455 | fdput(f); | 463 | fdput(f); |
| @@ -468,6 +476,18 @@ int do_select(int n, fd_set_bits *fds, struct timespec *end_time) | |||
| 468 | retval++; | 476 | retval++; |
| 469 | wait->_qproc = NULL; | 477 | wait->_qproc = NULL; |
| 470 | } | 478 | } |
| 479 | /* got something, stop busy polling */ | ||
| 480 | if (retval) { | ||
| 481 | can_busy_loop = false; | ||
| 482 | busy_flag = 0; | ||
| 483 | |||
| 484 | /* | ||
| 485 | * only remember a returned | ||
| 486 | * POLL_BUSY_LOOP if we asked for it | ||
| 487 | */ | ||
| 488 | } else if (busy_flag & mask) | ||
| 489 | can_busy_loop = true; | ||
| 490 | |||
| 471 | } | 491 | } |
| 472 | } | 492 | } |
| 473 | if (res_in) | 493 | if (res_in) |
| @@ -486,6 +506,17 @@ int do_select(int n, fd_set_bits *fds, struct timespec *end_time) | |||
| 486 | break; | 506 | break; |
| 487 | } | 507 | } |
| 488 | 508 | ||
| 509 | /* only if found POLL_BUSY_LOOP sockets && not out of time */ | ||
| 510 | if (can_busy_loop && !need_resched()) { | ||
| 511 | if (!busy_end) { | ||
| 512 | busy_end = busy_loop_end_time(); | ||
| 513 | continue; | ||
| 514 | } | ||
| 515 | if (!busy_loop_timeout(busy_end)) | ||
| 516 | continue; | ||
| 517 | } | ||
| 518 | busy_flag = 0; | ||
| 519 | |||
| 489 | /* | 520 | /* |
| 490 | * If this is the first loop and we have a timeout | 521 | * If this is the first loop and we have a timeout |
| 491 | * given, then we convert to ktime_t and set the to | 522 | * given, then we convert to ktime_t and set the to |
| @@ -717,7 +748,9 @@ struct poll_list { | |||
| 717 | * pwait poll_table will be used by the fd-provided poll handler for waiting, | 748 | * pwait poll_table will be used by the fd-provided poll handler for waiting, |
| 718 | * if pwait->_qproc is non-NULL. | 749 | * if pwait->_qproc is non-NULL. |
| 719 | */ | 750 | */ |
| 720 | static inline unsigned int do_pollfd(struct pollfd *pollfd, poll_table *pwait) | 751 | static inline unsigned int do_pollfd(struct pollfd *pollfd, poll_table *pwait, |
| 752 | bool *can_busy_poll, | ||
| 753 | unsigned int busy_flag) | ||
| 721 | { | 754 | { |
| 722 | unsigned int mask; | 755 | unsigned int mask; |
| 723 | int fd; | 756 | int fd; |
| @@ -731,7 +764,10 @@ static inline unsigned int do_pollfd(struct pollfd *pollfd, poll_table *pwait) | |||
| 731 | mask = DEFAULT_POLLMASK; | 764 | mask = DEFAULT_POLLMASK; |
| 732 | if (f.file->f_op && f.file->f_op->poll) { | 765 | if (f.file->f_op && f.file->f_op->poll) { |
| 733 | pwait->_key = pollfd->events|POLLERR|POLLHUP; | 766 | pwait->_key = pollfd->events|POLLERR|POLLHUP; |
| 767 | pwait->_key |= busy_flag; | ||
| 734 | mask = f.file->f_op->poll(f.file, pwait); | 768 | mask = f.file->f_op->poll(f.file, pwait); |
| 769 | if (mask & busy_flag) | ||
| 770 | *can_busy_poll = true; | ||
| 735 | } | 771 | } |
| 736 | /* Mask out unneeded events. */ | 772 | /* Mask out unneeded events. */ |
| 737 | mask &= pollfd->events | POLLERR | POLLHUP; | 773 | mask &= pollfd->events | POLLERR | POLLHUP; |
| @@ -750,6 +786,8 @@ static int do_poll(unsigned int nfds, struct poll_list *list, | |||
| 750 | ktime_t expire, *to = NULL; | 786 | ktime_t expire, *to = NULL; |
| 751 | int timed_out = 0, count = 0; | 787 | int timed_out = 0, count = 0; |
| 752 | unsigned long slack = 0; | 788 | unsigned long slack = 0; |
| 789 | unsigned int busy_flag = net_busy_loop_on() ? POLL_BUSY_LOOP : 0; | ||
| 790 | unsigned long busy_end = 0; | ||
| 753 | 791 | ||
| 754 | /* Optimise the no-wait case */ | 792 | /* Optimise the no-wait case */ |
| 755 | if (end_time && !end_time->tv_sec && !end_time->tv_nsec) { | 793 | if (end_time && !end_time->tv_sec && !end_time->tv_nsec) { |
| @@ -762,6 +800,7 @@ static int do_poll(unsigned int nfds, struct poll_list *list, | |||
| 762 | 800 | ||
| 763 | for (;;) { | 801 | for (;;) { |
| 764 | struct poll_list *walk; | 802 | struct poll_list *walk; |
| 803 | bool can_busy_loop = false; | ||
| 765 | 804 | ||
| 766 | for (walk = list; walk != NULL; walk = walk->next) { | 805 | for (walk = list; walk != NULL; walk = walk->next) { |
| 767 | struct pollfd * pfd, * pfd_end; | 806 | struct pollfd * pfd, * pfd_end; |
| @@ -776,9 +815,13 @@ static int do_poll(unsigned int nfds, struct poll_list *list, | |||
| 776 | * this. They'll get immediately deregistered | 815 | * this. They'll get immediately deregistered |
| 777 | * when we break out and return. | 816 | * when we break out and return. |
| 778 | */ | 817 | */ |
| 779 | if (do_pollfd(pfd, pt)) { | 818 | if (do_pollfd(pfd, pt, &can_busy_loop, |
| 819 | busy_flag)) { | ||
| 780 | count++; | 820 | count++; |
| 781 | pt->_qproc = NULL; | 821 | pt->_qproc = NULL; |
| 822 | /* found something, stop busy polling */ | ||
| 823 | busy_flag = 0; | ||
| 824 | can_busy_loop = false; | ||
| 782 | } | 825 | } |
| 783 | } | 826 | } |
| 784 | } | 827 | } |
| @@ -795,6 +838,17 @@ static int do_poll(unsigned int nfds, struct poll_list *list, | |||
| 795 | if (count || timed_out) | 838 | if (count || timed_out) |
| 796 | break; | 839 | break; |
| 797 | 840 | ||
| 841 | /* only if found POLL_BUSY_LOOP sockets && not out of time */ | ||
| 842 | if (can_busy_loop && !need_resched()) { | ||
| 843 | if (!busy_end) { | ||
| 844 | busy_end = busy_loop_end_time(); | ||
| 845 | continue; | ||
| 846 | } | ||
| 847 | if (!busy_loop_timeout(busy_end)) | ||
| 848 | continue; | ||
| 849 | } | ||
| 850 | busy_flag = 0; | ||
| 851 | |||
| 798 | /* | 852 | /* |
| 799 | * If this is the first loop and we have a timeout | 853 | * If this is the first loop and we have a timeout |
| 800 | * given, then we convert to ktime_t and set the to | 854 | * given, then we convert to ktime_t and set the to |
