virtio-blk: support called read/write in interrupt

Coredump need call the block read/write ops in interrupt
Not consider the ops called in thread and intterupt simultaneously.
Only used for coredump now.

Signed-off-by: Bowen Wang <wangbowen6@xiaomi.com>
This commit is contained in:
Bowen Wang
2023-12-06 19:37:10 +08:00
committed by Xiang Xiao
parent cd86499e83
commit 0fbfcf4caf
+53 -5
View File
@@ -175,6 +175,38 @@ static int g_virtio_blk_idx = 0;
* Private Functions * Private Functions
****************************************************************************/ ****************************************************************************/
/****************************************************************************
* Name: virtio_blk_wait_complete
*
* Description:
* Wait the virtio block request complete
*
****************************************************************************/
static void virtio_blk_wait_complete(FAR struct virtqueue *vq,
FAR sem_t *respsem)
{
if (up_interrupt_context())
{
for (; ; )
{
FAR sem_t * tmpsem = virtqueue_get_buffer(vq, NULL, NULL);
if (tmpsem == respsem)
{
break;
}
else if (tmpsem != NULL)
{
nxsem_post(tmpsem);
}
}
}
else
{
nxsem_wait_uninterruptible(respsem);
}
}
/**************************************************************************** /****************************************************************************
* Name: virtio_blk_rdwr * Name: virtio_blk_rdwr
* *
@@ -194,10 +226,17 @@ static ssize_t virtio_blk_rdwr(FAR struct virtio_blk_priv_s *priv,
ssize_t ret; ssize_t ret;
int readnum; int readnum;
ret = nxmutex_lock(&priv->lock); if (up_interrupt_context())
if (ret < 0)
{ {
return ret; virtqueue_disable_cb(vq);
}
else
{
ret = nxmutex_lock(&priv->lock);
if (ret < 0)
{
return ret;
}
} }
nxsem_init(&respsem, 0, 0); nxsem_init(&respsem, 0, 0);
@@ -233,7 +272,8 @@ static ssize_t virtio_blk_rdwr(FAR struct virtio_blk_priv_s *priv,
/* Wait for the request completion */ /* Wait for the request completion */
nxsem_wait_uninterruptible(&respsem); virtio_blk_wait_complete(vq, &respsem);
if (priv->resp->status != VIRTIO_BLK_S_OK) if (priv->resp->status != VIRTIO_BLK_S_OK)
{ {
vrterr("%s Error\n", write ? "Write" : "Read"); vrterr("%s Error\n", write ? "Write" : "Read");
@@ -241,7 +281,15 @@ static ssize_t virtio_blk_rdwr(FAR struct virtio_blk_priv_s *priv,
} }
err: err:
nxmutex_unlock(&priv->lock); if (up_interrupt_context())
{
virtqueue_enable_cb(vq);
}
else
{
nxmutex_unlock(&priv->lock);
}
return ret >= 0 ? nsectors : ret; return ret >= 0 ? nsectors : ret;
} }