[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Message-Id: <20191128174405.4244-1-anton.ivanov@cambridgegreys.com>
Date: Thu, 28 Nov 2019 17:44:05 +0000
From: anton.ivanov@...bridgegreys.com
To: linux-um@...ts.infradead.org
Cc: richard@....at, dan.carpenter@...cle.com, weiyongjun1@...wei.com,
kernel-janitors@...r.kernel.org, songliubraving@...com,
daniel@...earbox.net, ast@...nel.org, netdev@...r.kernel.org,
bpf@...r.kernel.org, kafai@...com,
Anton Ivanov <anton.ivanov@...bridgegreys.com>
Subject: [PATCH] um: vector: fix BPF loading in vector drivers
From: Anton Ivanov <anton.ivanov@...bridgegreys.com>
This fixes a possible hang in bpf firmware loading in the
UML vector io drivers due to use of GFP_KERNEL while holding
a spinlock.
Based on a prposed fix by weiyongjun1@...wei.com and suggestions for
improving it by dan.carpenter@...cle.com
Signed-off-by: Anton Ivanov <anton.ivanov@...bridgegreys.com>
---
arch/um/drivers/vector_kern.c | 38 ++++++++++++++++++-----------------
1 file changed, 20 insertions(+), 18 deletions(-)
diff --git a/arch/um/drivers/vector_kern.c b/arch/um/drivers/vector_kern.c
index 92617e16829e..dbbc6e850fdd 100644
--- a/arch/um/drivers/vector_kern.c
+++ b/arch/um/drivers/vector_kern.c
@@ -1387,6 +1387,7 @@ static int vector_net_load_bpf_flash(struct net_device *dev,
struct vector_private *vp = netdev_priv(dev);
struct vector_device *vdevice;
const struct firmware *fw;
+ void *new_filter;
int result = 0;
if (!(vp->options & VECTOR_BPF_FLASH)) {
@@ -1394,6 +1395,15 @@ static int vector_net_load_bpf_flash(struct net_device *dev,
return -1;
}
+ vdevice = find_device(vp->unit);
+
+ if (request_firmware(&fw, efl->data, &vdevice->pdev.dev))
+ return -1;
+
+ new_filter = kmemdup(fw->data, fw->size, GFP_KERNEL);
+ if (!new_filter)
+ goto free_buffer;
+
spin_lock(&vp->lock);
if (vp->bpf != NULL) {
@@ -1402,41 +1412,33 @@ static int vector_net_load_bpf_flash(struct net_device *dev,
kfree(vp->bpf->filter);
vp->bpf->filter = NULL;
} else {
- vp->bpf = kmalloc(sizeof(struct sock_fprog), GFP_KERNEL);
+ vp->bpf = kmalloc(sizeof(struct sock_fprog), GFP_ATOMIC);
if (vp->bpf == NULL) {
netdev_err(dev, "failed to allocate memory for firmware\n");
- goto flash_fail;
+ goto apply_flash_fail;
}
}
- vdevice = find_device(vp->unit);
-
- if (request_firmware(&fw, efl->data, &vdevice->pdev.dev))
- goto flash_fail;
-
- vp->bpf->filter = kmemdup(fw->data, fw->size, GFP_KERNEL);
- if (!vp->bpf->filter)
- goto free_buffer;
-
+ vp->bpf->filter = new_filter;
vp->bpf->len = fw->size / sizeof(struct sock_filter);
- release_firmware(fw);
if (vp->opened)
result = uml_vector_attach_bpf(vp->fds->rx_fd, vp->bpf);
spin_unlock(&vp->lock);
- return result;
-
-free_buffer:
release_firmware(fw);
-flash_fail:
+ return result;
+
+apply_flash_fail:
spin_unlock(&vp->lock);
- if (vp->bpf != NULL)
+ if (vp->bpf)
kfree(vp->bpf->filter);
kfree(vp->bpf);
- vp->bpf = NULL;
+
+free_buffer:
+ release_firmware(fw);
return -1;
}
--
2.20.1
Powered by blists - more mailing lists