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 /sound/oss/msnd_pinnacle.c | |
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>
Diffstat (limited to 'sound/oss/msnd_pinnacle.c')
-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 | ||