Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/netcan Don't kmem_alloc()/kmem_free() with spin lock hel...
details: https://anonhg.NetBSD.org/src/rev/9911c9d6472b
branches: trunk
changeset: 461951:9911c9d6472b
user: bouyer <bouyer%NetBSD.org@localhost>
date: Sat Jul 20 15:34:41 2019 +0000
description:
Don't kmem_alloc()/kmem_free() with spin lock held: call can_pcbsetfilter()
without canp_mtx; take it here and check canp_state before updating the
canp_filters.
diffstat:
sys/netcan/can.c | 6 ++----
sys/netcan/can_pcb.c | 33 +++++++++++++++++++++++----------
2 files changed, 25 insertions(+), 14 deletions(-)
diffs (98 lines):
diff -r f6a418bc9714 -r 9911c9d6472b sys/netcan/can.c
--- a/sys/netcan/can.c Sat Jul 20 13:29:36 2019 +0000
+++ b/sys/netcan/can.c Sat Jul 20 15:34:41 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: can.c,v 1.6 2018/11/15 10:23:56 maxv Exp $ */
+/* $NetBSD: can.c,v 1.7 2019/07/20 15:34:41 bouyer Exp $ */
/*-
* Copyright (c) 2003, 2017 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: can.c,v 1.6 2018/11/15 10:23:56 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: can.c,v 1.7 2019/07/20 15:34:41 bouyer Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -924,9 +924,7 @@
int nfilters = sopt->sopt_size / sizeof(struct can_filter);
if (sopt->sopt_size % sizeof(struct can_filter) != 0)
return EINVAL;
- mutex_enter(&canp->canp_mtx);
error = can_pcbsetfilter(canp, sopt->sopt_data, nfilters);
- mutex_exit(&canp->canp_mtx);
break;
}
default:
diff -r f6a418bc9714 -r 9911c9d6472b sys/netcan/can_pcb.c
--- a/sys/netcan/can_pcb.c Sat Jul 20 13:29:36 2019 +0000
+++ b/sys/netcan/can_pcb.c Sat Jul 20 15:34:41 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: can_pcb.c,v 1.7 2019/02/25 06:49:44 maxv Exp $ */
+/* $NetBSD: can_pcb.c,v 1.8 2019/07/20 15:34:41 bouyer Exp $ */
/*-
* Copyright (c) 2003, 2017 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: can_pcb.c,v 1.7 2019/02/25 06:49:44 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: can_pcb.c,v 1.8 2019/07/20 15:34:41 bouyer Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -193,8 +193,8 @@
so->so_pcb = NULL;
mutex_enter(&canp->canp_mtx);
can_pcbstate(canp, CANP_DETACHED);
+ mutex_exit(&canp->canp_mtx);
can_pcbsetfilter(canp, NULL, 0);
- mutex_exit(&canp->canp_mtx);
TAILQ_REMOVE(&canp->canp_table->canpt_queue, canp, canp_queue);
sofree(so); /* sofree drops the softnet_lock */
canp_unref(canp);
@@ -243,7 +243,9 @@
{
struct can_filter *newf;
- KASSERT(mutex_owned(&canp->canp_mtx));
+ struct can_filter *oldf;
+ int oldnf;
+ int error = 0;
if (nfilters > 0) {
newf =
@@ -252,13 +254,24 @@
} else {
newf = NULL;
}
- if (canp->canp_filters != NULL) {
- kmem_free(canp->canp_filters,
- sizeof(struct can_filter) * canp->canp_nfilters);
+ mutex_enter(&canp->canp_mtx);
+ oldf = canp->canp_filters;
+ oldnf = canp->canp_nfilters;
+ if (newf != NULL && canp->canp_state == CANP_DETACHED) {
+ error = ECONNRESET;
+ } else {
+ canp->canp_filters = newf;
+ canp->canp_nfilters = nfilters;
+ newf = NULL;
}
- canp->canp_filters = newf;
- canp->canp_nfilters = nfilters;
- return 0;
+ mutex_exit(&canp->canp_mtx);
+ if (oldf != NULL) {
+ kmem_free(oldf, sizeof(struct can_filter) * oldnf);
+ }
+ if (newf != NULL) {
+ kmem_free(newf, sizeof(struct can_filter) * nfilters);
+ }
+ return error;
}
Home |
Main Index |
Thread Index |
Old Index