diff --git a/sys/netinet/tcp_subr.c b/sys/netinet/tcp_subr.c --- a/sys/netinet/tcp_subr.c +++ b/sys/netinet/tcp_subr.c @@ -2720,8 +2720,12 @@ ksr->snd_tag->sw->snd_tag_status_str != NULL) { sz = SND_TAG_STATUS_MAXLEN; + in_pcbref(inp); + INP_RUNLOCK(inp); ksr->snd_tag->sw->snd_tag_status_str( ksr->snd_tag, NULL, &sz); + if (in_pcbrele_rlock(inp)) + return (EDEADLK); len += sz; } } @@ -2739,8 +2743,12 @@ kss->snd_tag->sw->snd_tag_status_str != NULL) { sz = SND_TAG_STATUS_MAXLEN; + in_pcbref(inp); + INP_RUNLOCK(inp); kss->snd_tag->sw->snd_tag_status_str( kss->snd_tag, NULL, &sz); + if (in_pcbrele_rlock(inp)) + return (EDEADLK); len += sz; } } @@ -2811,8 +2819,12 @@ if (ksr->snd_tag != NULL && ksr->snd_tag->sw->snd_tag_status_str != NULL) { sz = SND_TAG_STATUS_MAXLEN; + in_pcbref(inp); + INP_RUNLOCK(inp); ksr->snd_tag->sw->snd_tag_status_str( ksr->snd_tag, buf + len, &sz); + if (in_pcbrele_rlock(inp)) + return (EDEADLK); len += sz; } } @@ -2828,8 +2840,12 @@ if (kss->snd_tag != NULL && kss->snd_tag->sw->snd_tag_status_str != NULL) { sz = SND_TAG_STATUS_MAXLEN; + in_pcbref(inp); + INP_RUNLOCK(inp); kss->snd_tag->sw->snd_tag_status_str( kss->snd_tag, buf + len, &sz); + if (in_pcbrele_rlock(inp)) + return (EDEADLK); len += sz; } } @@ -2853,6 +2869,10 @@ zfree(buf, M_TEMP); return (error); + +again_reset: + req->oldidx = 0; + goto again; } static int