"Linux4.0 Device Driver Development" notes--Nineth: Asynchronous Notifications and synchronous I/O in Linux device drivers

Source: Internet
Author: User

Using asynchronous notifications in device drivers can make access to the device accessible to the application by the driver when it is accessible. Therefore, applications that use nonblocking I/O do not need to poll the device for access, and blocking access can be superseded by asynchronous notifications like "break". Asynchronous notifications are similar to the concept of "interrupts" on hardware, and the more accurate term is "signal-driven asynchronous I/O".

9.1 Concept and function of asynchronous notifications
    • Asynchronous notification: Once the device is ready, it proactively notifies the application that the application does not need to query the device state
    • comparison of several notification methods:
      • Blocking I/O: Wait until the device is accessible and start accessing
      • Non-blocking I/O: Use Poll () to query the device for access
      • Asynchronous notifications: Devices proactively notify user applications
      • -
9.2 Linux Asynchronous notification programming9.2.1 Linux Signal
    • Role: In Linux systems, asynchronous notifications use signals to implement
SIGHUP terminating process terminal line hangs SIGINT terminating process interrupt Process Sigquit establish core file termination process and generate core file Sigill build core file illegal directive Sigtrap build       Set core file tracking self-trapping Sigbus build core file Bus error SIGSEGV establish core file segment illegal error SIGFPE build core file floating point exception Sigiot build core file PerformI/OSelf-trapping Sigkill terminate process kill process sigpipe terminate process to a pipe without read process write data sigalarm terminate process timer to sigterm terminate process software terminate signal sigstop stop process Stop signal from non-terminal SIGTSTP stop signal stopped process terminal Sigcont ignore signal continue to execute a stopped process Sigurg ignore signalI/OEmergency signal Sigio Ignoring the signal descriptor can beI/OSIGCHLD ignore signal when a child process stops or exits notifies the parent process Sigttou stop process background process write terminal Sigttin stop process background process read Terminal SIGXGPU terminate process CPU time-out Sigxfsz Terminate process file length too long sigwinch ignore signal window size changes sigprof terminate process statistics distribution graph with timer to time SIGUSR1 terminate process user-defined signal1SIGUSR2 Terminate process user-defined signal2SIGVTALRM terminating process virtual timer to time
Reception of the 9.2.2 signal
    • signal capture function signal ()
      • parameter:
        • signum: Signal value
        • handler: processing function for Signum
          • If sig_ign: Ignore the signal
          • if SIG_DFL: system default processing
          • if user-defined function: signal is captured, the function is executed
      • return value
        • success: Last handler value of the handler function bound for signal Signum
        • failed: Return sig_err< /li>
      • sigaction ()
        • role: Changing the behavior of a process after receiving a specific signal
        • parameters
            Li>signum: Signal value
            • a specific valid signal except Sig_kill and sig_stop
          • Act: point to struct SI Pointer to an instance of Gaction
            • in struct sigaction, a function that processes the signal is specified, and if it is empty, the process processes the signal as a default
          • oldact: A handler function that holds the original corresponding signal, which can be set to null
int sigaction(int signo,conststruct sigaction *restrictstruct sigaction *restrict oact);
    • Example: using signals to implement asynchronous notifications
      • Readiness to release signals in user space processing devices
        • The owner of the device file is set up through the F_setown IO Control command for this process so that the signal is captured by this process
        • Set up device files to support Fasync, and asynchronous notification modes with F_SETFL IO control commands
        • Connecting signals and signal processing functions via the signal () function
//Start signal mechanismvoidSigterm_handler (intSigo) {CharData[max_len];intLen;len = Read (Stdin_fileno,&data,max_len);d Ata[len] =0;printf("Input available:%s\n", data);Exit(0);}intMainvoid){intOflags;//Start signal driving mechanismSignal (Sigio,sigterm_handler); Fcntl (Stdin_fileno,f_setown,getpid ()); oflags = Fcntl (STDIN_FILENO,F_GETFL); FCTCL ( Stdin_fileno,f_setfl,oflags | Fasync);//Build a dead loop to prevent the program from endingWhlie (1);return 0;}
Release of the 9.2.3 Signal (signals are released on the device drive side)
    • In order for the device to support the asynchronous notification mechanism, the following 3 tasks are involved in the driver
      • Support F_setown command, can be set in this control command processing filp->f_owner for the corresponding process ID. However, this work has been done by the kernel and the device driver does not need to handle
      • Support for F_SETFL command processing, the Fasync () function in the driver function is executed whenever the FASYNC flag is changed. Therefore, the Fasync () function should be implemented in the driver
      • Available in the device resource, call the Kill_fasync () function to fire the corresponding signal
      • -
    • asynchronous notification Programming in device drivers:
      • Handling Fasync Flag Change function: Fasync_helper ()
      • function to release signal: Kill_fasync ()
int fasync_helper(int fd,struct file *filp,int mode,structvoid kill_fasync(struct fasync_struct **fa,int sig,int band);
    • The best choice is to place the FASYNC_STRUCT structure pointer in the device structure body
//异步通知的设备结构体模板struct xxx_dev{    struct cdev cdev;    ...    struct fasync_struct *async_queue;//异步结构体指针};
    • In the Fasync () function in the device driver, simply pass the 3 parameters of the function and the pointer of the fasync_struct struct pointer as the fourth parameter to the Fasync_helper () function, and the template is as follows
staticint xxx_fasync(int fd,structint mode){  struct xxx_dev *dev = filp->private_data;  return fasync_helper(fd, filp, mode, &dev->async_queue);}
    • The Kill_fasync () function should be called when the device resource is available to release the Sigio signal, the third parameter is poll_in when read, and the third parameter is poll_out when writable, the template is as follows
static ssize_t xxx_write(struct file *filp,const char __user *buf,size_t count,loff_t *ppos){    struct xxx_dev *dev = filp->private_data;    ...    //产生异步读信息    if(dev->async_queue)    kill_fasync(&dev->async_queue,GIGIO,POLL_IN);    ...}
    • Finally, to remove the file from the asynchronous notification list when the file is closed
int xxx_release(struct inode *inode,struct file *filp){    //将文件从异步通知列表中删除    xxx_fasync(-1,filp,0);    ...    return0;}
9.4 Linux Asynchronous i/o9.4.1 AIO concept with GNU C library AIO9.4.1.1 AIO concept
    • The most common input-output (I/O) model in a synchronous i/o:linux system is synchronous I/O, in which the application is blocked when the request is made, knowing that the request satisfies

    • Asynchronous I/O:I/O requests may need to overlap with other processes

    • The most common input/output (I/O) models in Linux systems are synchronous I/O

      • In this model, when a request is made, the application blocks until the request is satisfied
      • The calling application does not need to use any central processing unit (CPU) while waiting for the I/O request to complete
      • In some cases, I/O requests may need to overlap with other processes, and the Portable Operating System interface (POSIX) asynchronous I/O (AIO) application Interface (API) provides this functionality
9.4.1.1 AIO Series API:
    • aio_read– Asynchronous Read
      • Function: Requests an asynchronous read and write operation on a valid file descriptor
        • When the request is queued, it returns immediately
        • This file descriptor can represent a file, socket, or even pipeline
      • Parameter AIOCB: The structure contains all the information transmitted and the user space buffers prepared for AIO operations
      • return value
        • Success: return 0
        • Failure: Returns-1, and sets the value of errno
intstruct aiocb *aiocbp );
    • aio_write– Asynchronous Write
      • Function: Request an asynchronous write operation
        • When the request is queued, it returns immediately
        • This file descriptor can represent a file, socket, or even pipeline
      • Parameter AIOCB: The structure contains all the information transmitted and the user space buffers prepared for AIO operations
      • return value
        • Success: return 0
        • Failure: Returns-1, and sets the value of errno
intstruct aiocb *aiocbp );
    • Aio_error
      • Role: Determine the status of the request
      • Parameter AIOCB: The structure contains all the information transmitted and the user space buffers prepared for AIO operations
      • return value
        • Einprogress: Description Request not completed
        • Ecanceled: Description Request canceled by application
        • Failure: Returns-1, and sets the value of errno
intstruct aiocb *aiocbp );
    • aio_return– getting the return value of an asynchronous operation
      • Another difference between asynchronous I/O and standard block I/O is that the return state of the function cannot be immediately accessed because it is not blocked on the read () call
      • In a standard read () call, the return state is provided when the function returns. But in asynchronous I/O, we're going to use the Aio_return () function
      • This function is called only after the Aio_error () call determines that the request has been completed (possibly successful or an error may have occurred)
      • Parameter AIOCB: The structure contains all the information transmitted and the user space buffers prepared for AIO operations
      • return value
        • Success: Returns the number of bytes transferred
        • Failure: Return-1
ssize_t aio_return( struct aiocb *aiocbp );
    • aio_suspend– suspend asynchronous operation until the asynchronous request completes
      • Action: Suspends (or blocks) the calling process until the asynchronous request completes, and the caller provides a list of AIOCB references, in which any completion will cause aio_suspend () to return
int  aio_suspend (const  struct  aiocb *const  cblist[], int  N, const  struct  timespec *timeout);  
    • aio_cancel– canceling an asynchronous request
      • Role: Allows the user to cancel one or all I/O requests performed on a file descriptor
      • Requirements:
        • If you want to cancel a request, the user needs to provide a file descriptor and a AIOCB reference
          • Function returned aio_canceled: request was successfully canceled
          • function return aio_notcanceled: Request complete
        • If you want to cancel all requests for a given file descriptor, the user needs to provide a descriptor for the file and a NULL reference to AIOCBP
          • function returns aio_canceled: Indicates that all requests have been canceled.
          • function returns aio_notcanceled: Indicates that at least one request has not been canceled
          • function returns Aio_alldone: Indicates that no request can be canceled
        • Use Aio_error () to validate each AIO request
          • Aio_error () returns 1 and sets the errno set to ecanceled: Indicates that a request has been canceled
intintstruct aiocb *aiocbp );
    • lio_listio– simultaneously initiates multiple transmissions (one system call can initiate a large number of I/O operations)
      • Role: This function is very important, which allows the user to initiate a large number of I/O operations in a system call (one kernel context switch)
      • Parameters
        • Mode: Can be lio_wait or lio_nowait
          • LIO_WAIT will block this call until all I/O is complete.
          • After the operation is queued, the lio_nowait will return
        • List: is a AIOCB reference, the maximum number of elements is defined by nent
          • If the element of list is Null,lio_listio () it is ignored.
intintstruct aiocb *listintstruct sigevent *sig );
9.4.2 Linux kernel Aio and Libaio
    • Linux AIO can also be implemented by kernel space, asynchronous I/O is the standard feature of the linux2.6 version kernel
    • for block devices, AIO can emit a large number of read/write calls at once and pass the generic block layer i/ o Scheduling for better performance, users can also reduce excessive synchronization load
    • for network devices, you can also use AIO at the socket level, allowing the CPU and NIC to be fully overlapped to improve throughput performance
    • System calls to kernel AIO that are typically combined with Libaio in user space
io_setup( )//Initializes an asynchronous context for the current processio_submit( )//Submits one or more asynchronous I/O operationsio_getevents( )//Gets the completion status of some outstanding asynchronous I/O operationsio_cancel( )//Cancels an outstanding I/O operationio_destroy( )//Removes an asynchronous context for the current process
9.4.3 AIO and device driver
    • After user space calls Io_submit (), the kernel generates a corresponding KIOCB structure corresponding to each IOCB structure that the user passes.
    • Determine whether a KIOCB is a synchronous I/O request through IS_SYNC_KIOCB

      • If the return is true, it is expressed as an asynchronous I/O request
    • Character device: You must explicitly support AIO (very few asynchronous I/O operations)

    • The character device driver file_operations contains 3 AIO-related member functions,
ssize_t (*aio_read*iocb*buffer, size_t count, loff_t offset);ssize_t (*aio_write*iocb*buffer, size_t count, loff_t offset);int (*aio_fsync*iocbint datasync);
    • Block devices and network devices: they are asynchronous in nature

Linux4.0 Device Driver Development notes--Nineth: Asynchronous Notifications and synchronous I/O in Linux device drivers

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.