On Mon, Jan 23, 2017 at 10:10:23AM +1000, Martin Pieuchot wrote:
> On 22/01/17(Sun) 20:38, David Gwynne wrote:
> > ifqueues count packets, therefore if_enqueue doesnt have to.
> >
> > this adds reading of the ifq counters into the if_data values so
> > userland still looks right.
> >
> > this is another step toward multiple tx queues.
>
> I like it, some comments below.
>
>
> > @@ -1799,10 +1790,13 @@ ifioctl(struct socket *so, u_long cmd, c
> > ifr->ifr_hardmtu = ifp->if_hardmtu;
> > break;
> >
> > - case SIOCGIFDATA:
> > - error = copyout((caddr_t)&ifp->if_data, ifr->ifr_data,
> > + case SIOCGIFDATA: {
> > + struct if_data data;
>
> I'd use ifdata that would avoid shadowing the 'data' pointer.
ok.
> > + error = copyout((caddr_t)&ifp->if_data, &data,
> > sizeof(ifp->if_data));
>
> Shouldn't this be:
>
> copyout(&data, ifr->ifr_data, sizeof(data))
yes.
> > +void
> > +if_data(struct if_data *data, struct ifnet *ifp)
>
> Could you pass ``ifp'' as first argument to keep coherency with the rest
> of if.c?
i can. i thought of it as a memcpy like function, so dst src.
fixed.
> > + /* it's ugly reaching into an ifq like this */
>
> What's ugly? I'm not sure this comment help.
if.c doesnt know much about ifq internals, except for this bit.
Index: if.c
===================================================================
RCS file: /cvs/src/sys/net/if.c,v
retrieving revision 1.475
diff -u -p -r1.475 if.c
--- if.c 22 Jan 2017 10:17:39 -0000 1.475
+++ if.c 23 Jan 2017 00:32:53 -0000
@@ -583,8 +583,7 @@ if_start_locked(struct ifnet *ifp)
int
if_enqueue(struct ifnet *ifp, struct mbuf *m)
{
- int length, error = 0;
- unsigned short mflags;
+ int error = 0;
#if NBRIDGE > 0
if (ifp->if_bridgeport && (m->m_flags & M_PROTO1) == 0) {
@@ -595,9 +594,6 @@ if_enqueue(struct ifnet *ifp, struct mbu
}
#endif
- length = m->m_pkthdr.len;
- mflags = m->m_flags;
-
#if NPF > 0
pf_pkt_unlink_state_key(m);
#endif /* NPF > 0 */
@@ -610,11 +606,6 @@ if_enqueue(struct ifnet *ifp, struct mbu
if (error)
return (error);
- ifp->if_opackets++;
- ifp->if_obytes += length;
- if (mflags & M_MCAST)
- ifp->if_omcasts++;
-
if_start(ifp);
return (0);
@@ -1799,10 +1790,12 @@ ifioctl(struct socket *so, u_long cmd, c
ifr->ifr_hardmtu = ifp->if_hardmtu;
break;
- case SIOCGIFDATA:
- error = copyout((caddr_t)&ifp->if_data, ifr->ifr_data,
- sizeof(ifp->if_data));
+ case SIOCGIFDATA: {
+ struct if_data ifdata;
+ if_data(ifp, &ifdata);
+ error = copyout(&ifdata, &ifr->ifr_data, sizeof(ifdata));
break;
+ }
case SIOCSIFFLAGS:
if ((error = suser(p, 0)) != 0)
@@ -2167,6 +2160,33 @@ ifconf(u_long cmd, caddr_t data)
}
ifc->ifc_len -= space;
return (error);
+}
+
+void
+if_data(struct ifnet *ifp, struct if_data *data)
+{
+ struct ifqueue *ifq;
+ uint64_t opackets = 0;
+ uint64_t obytes = 0;
+ uint64_t omcasts = 0;
+ uint64_t oqdrops = 0;
+
+ ifq = &ifp->if_snd;
+
+ mtx_enter(&ifq->ifq_mtx);
+ opackets += ifq->ifq_packets;
+ obytes += ifq->ifq_bytes;
+ oqdrops += ifq->ifq_qdrops;
+ omcasts += ifq->ifq_mcasts;
+ /* ifq->ifq_errors */
+ mtx_leave(&ifq->ifq_mtx);
+
+ *data = ifp->if_data;
+ data->ifi_opackets += opackets;
+ data->ifi_obytes += obytes;
+ data->ifi_oqdrops += oqdrops;
+ data->ifi_omcasts += omcasts;
+ /* ifp->if_data.ifi_oerrors */
}
/*
Index: if.h
===================================================================
RCS file: /cvs/src/sys/net/if.h,v
retrieving revision 1.181
diff -u -p -r1.181 if.h
--- if.h 12 Dec 2016 09:51:30 -0000 1.181
+++ if.h 23 Jan 2017 00:32:53 -0000
@@ -469,6 +469,7 @@ void if_downall(void);
void if_link_state_change(struct ifnet *);
void if_up(struct ifnet *);
int ifconf(u_long, caddr_t);
+void if_data(struct ifnet *, struct if_data *);
void ifinit(void);
int ifioctl(struct socket *, u_long, caddr_t, struct proc *);
int ifpromisc(struct ifnet *, int);
Index: rtsock.c
===================================================================
RCS file: /cvs/src/sys/net/rtsock.c,v
retrieving revision 1.216
diff -u -p -r1.216 rtsock.c
--- rtsock.c 22 Jan 2017 04:31:02 -0000 1.216
+++ rtsock.c 23 Jan 2017 00:32:53 -0000
@@ -1268,7 +1268,7 @@ rt_ifmsg(struct ifnet *ifp)
ifm->ifm_tableid = ifp->if_rdomain;
ifm->ifm_flags = ifp->if_flags;
ifm->ifm_xflags = ifp->if_xflags;
- ifm->ifm_data = ifp->if_data;
+ if_data(ifp, &ifm->ifm_data);
ifm->ifm_addrs = 0;
route_input(m, AF_UNSPEC);
}
@@ -1473,7 +1473,7 @@ sysctl_iflist(int af, struct walkarg *w)
ifm->ifm_index = ifp->if_index;
ifm->ifm_tableid = ifp->if_rdomain;
ifm->ifm_flags = ifp->if_flags;
- ifm->ifm_data = ifp->if_data;
+ if_data(ifp, &ifm->ifm_data);
ifm->ifm_addrs = info.rti_addrs;
error = copyout(ifm, w->w_where, len);
if (error)