I'm trying to write a linux character driver which implements a "tagged MUX" functionality writing to a special hardware link.
write()
requests to the driver feed data into a kfifo
and a separate kernel thread pulls the data from the FIFO as appropriate. If the FIFO is full, user-space writers to the file descriptor should block until FIFO space is available.
How do you implement such blocking in a character device driver?
I tried this in the "write" handler of my character driver. The user-space process did indeed block when the FIFO was full but it could not be interrupted or killed. Had to reboot the machine.
ssize_t
fifoWrite(struct file *pFile, const char __user *pUserData, size_t nBytes, loff_t *pOffset)
{
unsigned char *pktData = 0;
pktData = memdup_user(pUserData, nBytes); // copy n bytes from user to kernel
if (IS_ERR(pktData))
return PTR_ERR(pktData);
TDataPacket pkt;
memcpy(pkt.buf, pktData, nBytes);
while (kfifo_put(&pktFifo, pkt) == 0)
{
printk(KERN_ERR MODULE_NAME": write - FIFO full\n");
msleep(1000);
}
int fifoLen = kfifo_len(&clientInfo->pktFifo);
printk(KERN_INFO MODULE_NAME": WRITE - %zu bytes. LEN %d\n", , nBytes, fifoLen);
kfree(pktData);
return nBytes;
}
After searching for a long time, these resources proved to be very helpful: