Module Name: src Committed By: ozaki-r Date: Thu Jan 25 03:09:05 UTC 2018
Modified Files: src/sys/net: rtsock.c Log Message: Fix another deadlock When waiting for a route update to finish, a waiter has to release its reference to the route to avoid a deadlock. Because a updater tries to wait for references to a target route (except for a reference by the updater itself) to be released. To generate a diff of this commit: cvs rdiff -u -r1.237 -r1.238 src/sys/net/rtsock.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/net/rtsock.c diff -u src/sys/net/rtsock.c:1.237 src/sys/net/rtsock.c:1.238 --- src/sys/net/rtsock.c:1.237 Fri Jan 19 05:19:29 2018 +++ src/sys/net/rtsock.c Thu Jan 25 03:09:05 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: rtsock.c,v 1.237 2018/01/19 05:19:29 ozaki-r Exp $ */ +/* $NetBSD: rtsock.c,v 1.238 2018/01/25 03:09:05 ozaki-r Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -61,7 +61,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.237 2018/01/19 05:19:29 ozaki-r Exp $"); +__KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.238 2018/01/25 03:09:05 ozaki-r Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -1015,11 +1015,21 @@ COMPATNAME(route_output)(struct mbuf *m, * Release rt_so_mtx to avoid a deadlock with route_intr * and also serialize updating routes to avoid another. */ + if (rt_updating) { + /* Release to allow the updater to proceed */ + rt_unref(rt); + rt = NULL; + } while (rt_updating) { error = cv_wait_sig(&rt_update_cv, rt_so_mtx); if (error != 0) goto flush; } + if (rt == NULL) { + error = rtrequest1(RTM_GET, &info, &rt); + if (error != 0) + goto flush; + } rt_updating = true; mutex_exit(rt_so_mtx);