2012-09-04 30 views
3

我寫了一個小驅動程序來讀取一些數據並將其提供給用戶。我的驅動程序可以被多個應用程序使用,即它是一個可重入驅動程序,因此使用自旋鎖。但我發現copy_to_user不應該被稱爲與自旋鎖持有。在以下代碼中爲char_device_buf爲共享數據;我必須保護它。除互斥體之外是否有任何機制使用自旋鎖並使用copy_to_user如果需要調用copy_to_user,如何使用旋轉鎖定?

static ssize_t char_dev_read(struct file *file, 
           char *buf, 
           size_t lbuf, 
           loff_t *ppos) 
    { 
      int maxbytes; /* number of bytes from ppos to MAX_LENGTH */ 
      int bytes_to_do; /* number of bytes to read */ 
      int nbytes; /* number of bytes actually read */ 

      maxbytes = MAX_LENGTH - *ppos; 

      if(maxbytes > lbuf) bytes_to_do = lbuf; 
      else bytes_to_do = maxbytes; 

      if(bytes_to_do == 0) { 
        printk("Reached end of device\n"); 
        return -ENOSPC; /* Causes read() to return EOF */ 
      } 

     /* Tesing for accidental release */ 
    //    accidental_release(); 

      printk(KERN_DEBUG "READER: trying for critical region lock \n"); 

      spin_lock(&myspin);/*begin of critical region */ 

        printk(KERN_DEBUG "READER : acquired lock: executing critical code\n"); 
        nbytes = bytes_to_do - 
          copy_to_user(buf, /* to */ 
              char_device_buf + *ppos, /* from */ 
              bytes_to_do); /* how many bytes */ 


      spin_unlock(&myspin); /* end of critical region */ 
      *ppos += nbytes; 
      return nbytes; 
    } 

回答

5

copy_{to,from}_user不應該用在自旋鎖裏面的原因是,這些功能可以睡覺。想象一下這個場景(單處理器計算機上):

  1. 進程A mmap()編輯文件
  2. 該進程調用驅動程序提供的地址到該mmap()編輯區域
  3. 你的代碼運行時,鎖,然後copy_to_user會在該地址上導致頁面錯誤 - 內存不存在,因此進程會進入休眠狀態,直到數據來自磁盤。
  4. 內核調度處理B,它以同樣的方式調用你的驅動程序。
  5. 死鎖 - 進程A正在等待IO在鎖內返回,但不會被調度,因爲B正在等待CPU解鎖同一個鎖。

除非有一個100%的保證,copy_{to,from}_user不會造成段錯誤,你不能使用自旋鎖,但必須使用睡眠鎖代替,如「的mutex_lock」。睡眠鎖對調度程序產生控制,而自旋鎖則不能。

+0

在多處理器中,進程B將有機會在其他處理器上執行。因此,系統不會停止。一旦頁表正確加載,它將從睡眠中出來,代碼將被正確執行。我在這裏看不到多處理器上的任何問題。無論如何,自旋鎖在單處理器中無用,因爲我們都知道這一點。我不明白在多處理器上的例子sleep()的缺點。你可以在多處理器環境中拋出問題嗎? –

+0

在多處理器上,你可能遇到同樣的問題。假設進程A在保持螺旋鎖的同時被調度出來。現在,調度程序可以將任何任務放在任何CPU上。假設它無意中安排所有的CPU運行一些恰好鎖定該自旋鎖的代碼,那麼你會遇到死鎖,因爲原來的線程永遠不會被喚醒釋放它。在等待螺旋鎖的CPU上不會發生調度。 'copy_to_user'示例只是需要調度程序休眠的情況的一個示例。對於任何其他情況下,您持有自旋鎖,然後安排 - 您可能會陷入僵局。 –

相關問題