mirror of https://gitee.com/openkylin/linux.git
Merge branch 'nvme-4.19' of git://git.infradead.org/nvme into for-linus
Pull single NVMe fix from Christoph. * 'nvme-4.19' of git://git.infradead.org/nvme: nvmet-rdma: fix possible bogus dereference under heavy load
This commit is contained in:
commit
bf93585ee1
|
@ -66,6 +66,7 @@ struct nvmet_rdma_rsp {
|
||||||
|
|
||||||
struct nvmet_req req;
|
struct nvmet_req req;
|
||||||
|
|
||||||
|
bool allocated;
|
||||||
u8 n_rdma;
|
u8 n_rdma;
|
||||||
u32 flags;
|
u32 flags;
|
||||||
u32 invalidate_rkey;
|
u32 invalidate_rkey;
|
||||||
|
@ -174,11 +175,19 @@ nvmet_rdma_get_rsp(struct nvmet_rdma_queue *queue)
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
spin_lock_irqsave(&queue->rsps_lock, flags);
|
spin_lock_irqsave(&queue->rsps_lock, flags);
|
||||||
rsp = list_first_entry(&queue->free_rsps,
|
rsp = list_first_entry_or_null(&queue->free_rsps,
|
||||||
struct nvmet_rdma_rsp, free_list);
|
struct nvmet_rdma_rsp, free_list);
|
||||||
list_del(&rsp->free_list);
|
if (likely(rsp))
|
||||||
|
list_del(&rsp->free_list);
|
||||||
spin_unlock_irqrestore(&queue->rsps_lock, flags);
|
spin_unlock_irqrestore(&queue->rsps_lock, flags);
|
||||||
|
|
||||||
|
if (unlikely(!rsp)) {
|
||||||
|
rsp = kmalloc(sizeof(*rsp), GFP_KERNEL);
|
||||||
|
if (unlikely(!rsp))
|
||||||
|
return NULL;
|
||||||
|
rsp->allocated = true;
|
||||||
|
}
|
||||||
|
|
||||||
return rsp;
|
return rsp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -187,6 +196,11 @@ nvmet_rdma_put_rsp(struct nvmet_rdma_rsp *rsp)
|
||||||
{
|
{
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
|
if (rsp->allocated) {
|
||||||
|
kfree(rsp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
spin_lock_irqsave(&rsp->queue->rsps_lock, flags);
|
spin_lock_irqsave(&rsp->queue->rsps_lock, flags);
|
||||||
list_add_tail(&rsp->free_list, &rsp->queue->free_rsps);
|
list_add_tail(&rsp->free_list, &rsp->queue->free_rsps);
|
||||||
spin_unlock_irqrestore(&rsp->queue->rsps_lock, flags);
|
spin_unlock_irqrestore(&rsp->queue->rsps_lock, flags);
|
||||||
|
@ -776,6 +790,15 @@ static void nvmet_rdma_recv_done(struct ib_cq *cq, struct ib_wc *wc)
|
||||||
|
|
||||||
cmd->queue = queue;
|
cmd->queue = queue;
|
||||||
rsp = nvmet_rdma_get_rsp(queue);
|
rsp = nvmet_rdma_get_rsp(queue);
|
||||||
|
if (unlikely(!rsp)) {
|
||||||
|
/*
|
||||||
|
* we get here only under memory pressure,
|
||||||
|
* silently drop and have the host retry
|
||||||
|
* as we can't even fail it.
|
||||||
|
*/
|
||||||
|
nvmet_rdma_post_recv(queue->dev, cmd);
|
||||||
|
return;
|
||||||
|
}
|
||||||
rsp->queue = queue;
|
rsp->queue = queue;
|
||||||
rsp->cmd = cmd;
|
rsp->cmd = cmd;
|
||||||
rsp->flags = 0;
|
rsp->flags = 0;
|
||||||
|
|
Loading…
Reference in New Issue