in_pcb: add helper for deferring inpcb rele calls from list functions

This commit is contained in:
mmacy 2018-05-20 02:17:30 +00:00
parent 8b5d41008d
commit 99ec59840b
2 changed files with 31 additions and 0 deletions

View File

@ -1314,6 +1314,28 @@ in_pcbrele(struct inpcb *inp)
return (in_pcbrele_wlocked(inp));
}
void
in_pcblist_rele_rlocked(epoch_context_t ctx)
{
struct in_pcblist *il;
struct inpcb *inp;
struct inpcbinfo *pcbinfo;
int i, n;
il = __containerof(ctx, struct in_pcblist, il_epoch_ctx);
pcbinfo = il->il_pcbinfo;
n = il->il_count;
INP_INFO_WLOCK(pcbinfo);
for (i = 0; i < n; i++) {
inp = il->il_inp_list[i];
INP_RLOCK(inp);
if (!in_pcbrele_rlocked(inp))
INP_RUNLOCK(inp);
}
INP_INFO_WUNLOCK(pcbinfo);
free(il, M_TEMP);
}
/*
* Unconditionally schedule an inpcb to be freed by decrementing its
* reference count, which should occur only after the inpcb has been detached

View File

@ -41,6 +41,7 @@
#define _NETINET_IN_PCB_H_
#include <sys/queue.h>
#include <sys/epoch.h>
#include <sys/_lock.h>
#include <sys/_mutex.h>
#include <sys/_rwlock.h>
@ -407,6 +408,13 @@ struct inpcbport {
u_short phd_port;
};
struct in_pcblist {
int il_count;
struct epoch_context il_epoch_ctx;
struct inpcbinfo *il_pcbinfo;
struct inpcb *il_inp_list[0];
};
/*-
* Global data structure for each high-level protocol (UDP, TCP, ...) in both
* IPv4 and IPv6. Holds inpcb lists and information for managing them.
@ -829,6 +837,7 @@ void in_pcbrehash_mbuf(struct inpcb *, struct mbuf *);
int in_pcbrele(struct inpcb *);
int in_pcbrele_rlocked(struct inpcb *);
int in_pcbrele_wlocked(struct inpcb *);
void in_pcblist_rele_rlocked(epoch_context_t ctx);
void in_losing(struct inpcb *);
void in_pcbsetsolabel(struct socket *so);
int in_getpeeraddr(struct socket *so, struct sockaddr **nam);