diff options
| author | Arnd Bergmann <arnd@arndb.de> | 2014-01-02 07:07:47 -0500 |
|---|---|---|
| committer | Takashi Iwai <tiwai@suse.de> | 2014-01-14 10:01:20 -0500 |
| commit | 1a21576562507b2b10b9aa53555857868fe51c94 (patch) | |
| tree | 4b251c8c370ee4d31799ddc756388239712c2386 | |
| parent | cf67c8e71bc15cf6b1843ab88c31cf732f2f2ff0 (diff) | |
sound: oss: msnd_pinnacle: avoid interruptible_sleep_on_timeout
We want to remove all sleep_on variants from the kernel because they are
racy. In case of the pinnacle driver, we can replace
interruptible_sleep_on_timeout with wait_event_interruptible_timeout
by changing the meaning of a few flags used in the driver so they
are cleared at wakeup time, which is a somewhat more appropriate
way to do the same, although probably still racy.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
| -rw-r--r-- | sound/oss/msnd_pinnacle.c | 31 |
1 files changed, 18 insertions, 13 deletions
diff --git a/sound/oss/msnd_pinnacle.c b/sound/oss/msnd_pinnacle.c index 11ff7c55240c..c23f9f95bfa5 100644 --- a/sound/oss/msnd_pinnacle.c +++ b/sound/oss/msnd_pinnacle.c | |||
| @@ -664,12 +664,15 @@ static long dev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
| 664 | 664 | ||
| 665 | static void dsp_write_flush(void) | 665 | static void dsp_write_flush(void) |
| 666 | { | 666 | { |
| 667 | int timeout = get_play_delay_jiffies(dev.DAPF.len); | ||
| 668 | |||
| 667 | if (!(dev.mode & FMODE_WRITE) || !test_bit(F_WRITING, &dev.flags)) | 669 | if (!(dev.mode & FMODE_WRITE) || !test_bit(F_WRITING, &dev.flags)) |
| 668 | return; | 670 | return; |
| 669 | set_bit(F_WRITEFLUSH, &dev.flags); | 671 | set_bit(F_WRITEFLUSH, &dev.flags); |
| 670 | interruptible_sleep_on_timeout( | 672 | wait_event_interruptible_timeout( |
| 671 | &dev.writeflush, | 673 | dev.writeflush, |
| 672 | get_play_delay_jiffies(dev.DAPF.len)); | 674 | !test_bit(F_WRITEFLUSH, &dev.flags), |
| 675 | timeout); | ||
| 673 | clear_bit(F_WRITEFLUSH, &dev.flags); | 676 | clear_bit(F_WRITEFLUSH, &dev.flags); |
| 674 | if (!signal_pending(current)) { | 677 | if (!signal_pending(current)) { |
| 675 | current->state = TASK_INTERRUPTIBLE; | 678 | current->state = TASK_INTERRUPTIBLE; |
| @@ -897,6 +900,7 @@ static int dsp_read(char __user *buf, size_t len) | |||
| 897 | { | 900 | { |
| 898 | int count = len; | 901 | int count = len; |
| 899 | char *page = (char *)__get_free_page(GFP_KERNEL); | 902 | char *page = (char *)__get_free_page(GFP_KERNEL); |
| 903 | int timeout = get_rec_delay_jiffies(DAR_BUFF_SIZE); | ||
| 900 | 904 | ||
| 901 | if (!page) | 905 | if (!page) |
| 902 | return -ENOMEM; | 906 | return -ENOMEM; |
| @@ -936,11 +940,11 @@ static int dsp_read(char __user *buf, size_t len) | |||
| 936 | 940 | ||
| 937 | if (count > 0) { | 941 | if (count > 0) { |
| 938 | set_bit(F_READBLOCK, &dev.flags); | 942 | set_bit(F_READBLOCK, &dev.flags); |
| 939 | if (!interruptible_sleep_on_timeout( | 943 | if (wait_event_interruptible_timeout( |
| 940 | &dev.readblock, | 944 | dev.readblock, |
| 941 | get_rec_delay_jiffies(DAR_BUFF_SIZE))) | 945 | test_bit(F_READBLOCK, &dev.flags), |
| 946 | timeout) <= 0) | ||
| 942 | clear_bit(F_READING, &dev.flags); | 947 | clear_bit(F_READING, &dev.flags); |
| 943 | clear_bit(F_READBLOCK, &dev.flags); | ||
| 944 | if (signal_pending(current)) { | 948 | if (signal_pending(current)) { |
| 945 | free_page((unsigned long)page); | 949 | free_page((unsigned long)page); |
| 946 | return -EINTR; | 950 | return -EINTR; |
| @@ -955,6 +959,7 @@ static int dsp_write(const char __user *buf, size_t len) | |||
| 955 | { | 959 | { |
| 956 | int count = len; | 960 | int count = len; |
| 957 | char *page = (char *)__get_free_page(GFP_KERNEL); | 961 | char *page = (char *)__get_free_page(GFP_KERNEL); |
| 962 | int timeout = get_play_delay_jiffies(DAP_BUFF_SIZE); | ||
| 958 | 963 | ||
| 959 | if (!page) | 964 | if (!page) |
| 960 | return -ENOMEM; | 965 | return -ENOMEM; |
| @@ -995,10 +1000,10 @@ static int dsp_write(const char __user *buf, size_t len) | |||
| 995 | 1000 | ||
| 996 | if (count > 0) { | 1001 | if (count > 0) { |
| 997 | set_bit(F_WRITEBLOCK, &dev.flags); | 1002 | set_bit(F_WRITEBLOCK, &dev.flags); |
| 998 | interruptible_sleep_on_timeout( | 1003 | wait_event_interruptible_timeout( |
| 999 | &dev.writeblock, | 1004 | dev.writeblock, |
| 1000 | get_play_delay_jiffies(DAP_BUFF_SIZE)); | 1005 | test_bit(F_WRITEBLOCK, &dev.flags), |
| 1001 | clear_bit(F_WRITEBLOCK, &dev.flags); | 1006 | timeout); |
| 1002 | if (signal_pending(current)) { | 1007 | if (signal_pending(current)) { |
| 1003 | free_page((unsigned long)page); | 1008 | free_page((unsigned long)page); |
| 1004 | return -EINTR; | 1009 | return -EINTR; |
| @@ -1044,7 +1049,7 @@ static __inline__ void eval_dsp_msg(register WORD wMessage) | |||
| 1044 | clear_bit(F_WRITING, &dev.flags); | 1049 | clear_bit(F_WRITING, &dev.flags); |
| 1045 | } | 1050 | } |
| 1046 | 1051 | ||
| 1047 | if (test_bit(F_WRITEBLOCK, &dev.flags)) | 1052 | if (test_and_clear_bit(F_WRITEBLOCK, &dev.flags)) |
| 1048 | wake_up_interruptible(&dev.writeblock); | 1053 | wake_up_interruptible(&dev.writeblock); |
| 1049 | break; | 1054 | break; |
| 1050 | 1055 | ||
| @@ -1055,7 +1060,7 @@ static __inline__ void eval_dsp_msg(register WORD wMessage) | |||
| 1055 | 1060 | ||
| 1056 | pack_DARQ_to_DARF(dev.last_recbank); | 1061 | pack_DARQ_to_DARF(dev.last_recbank); |
| 1057 | 1062 | ||
| 1058 | if (test_bit(F_READBLOCK, &dev.flags)) | 1063 | if (test_and_clear_bit(F_READBLOCK, &dev.flags)) |
| 1059 | wake_up_interruptible(&dev.readblock); | 1064 | wake_up_interruptible(&dev.readblock); |
| 1060 | break; | 1065 | break; |
| 1061 | 1066 | ||
