Подробности

[В начало]

Проблема в реализации № L0025

Краткое описание

drivers/media/radio/si470x/radio-si470x-common.c: двойной mutex_lock в si470x_fops_read()

Подробное описание

  • Первый mutex_lock(&radio->lock) в строке 441.
  • Второй mutex_lock(&radio->lock) в строке 462.
  •  433static ssize_t si470x_fops_read(struct file *file, char __user *buf,
     434                size_t count, loff_t *ppos)
     435{
    ....
     441        mutex_lock(&radio->lock);
     442        if ((radio->registers[SYSCONFIG1] & SYSCONFIG1_RDS) == 0)
     443                si470x_rds_on(radio);
     444
     445        /* block if no new data available */
     446        while (radio->wr_index == radio->rd_index) {
     447                if (file->f_flags & O_NONBLOCK) {
     448                        retval = -EWOULDBLOCK;
     449                        goto done;
     450                }
     451                if (wait_event_interruptible(radio->read_queue,
     452                        radio->wr_index != radio->rd_index) < 0) {
     453                        retval = -EINTR;
     454                        goto done;
     455                }
     456        }
     457
     458        /* calculate block count from byte count */
     459        count /= 3;
     460
     461        /* copy RDS block out of internal buffer and to user buffer */
     462        mutex_lock(&radio->lock);
    

    Способы устранения

     drivers/media/radio/si470x/radio-si470x-common.c |    1 -
     1 files changed, 0 insertions(+), 1 deletions(-)
    diff --git a/drivers/media/radio/si470x/radio-si470x-common.c b/drivers/media/radio/si470x/radio-si470x-common.c
    index 60c176f..38ae6cd 100644
    --- a/drivers/media/radio/si470x/radio-si470x-common.c
    +++ b/drivers/media/radio/si470x/radio-si470x-common.c
    @@ -460,7 +460,6 @@ static ssize_t si470x_fops_read(struct file *file, char __user *buf,
     	count /= 3;
     
     	/* copy RDS block out of internal buffer and to user buffer */
    -	mutex_lock(&radio->lock);
     	while (block_count < count) {
     		if (radio->rd_index == radio->wr_index)
     			break;
    -- 
    

    Компонент

    linux-kernel 2.6.37

    Принято

    https://lkml.org/lkml/2011/1/23/11
    commit

    Статус

    Исправлено в ядре 2.6.39-rc1

    [В начало]