Re: fread optimization

2015-01-21 Thread Theo de Raadt
  +#define MINIMUM(a, b)  (((a)  (b)) ? (a) : (b))
 
 you don't want to use the MIN from sys/param.h? many files in libc
 already do. (though admittedly fvwrite.c defines its own, but that
 seems like a bug.)

I guess you haven't observed the commits of the last week...

I am certain you know sys/param.h creates much namespace pollution
on all systems.  This is largely unavoidable since this is a poorly
specified legacy header.  Recently I went through efforts to limit the
pollution, and to limit pulling in the pollution.

The base system now uses POSIX limits.h rather than sys/param.h,
wherever possible.  Simultaneously, sys/param.h has been wittled
down to not expose many symbols which are CSRGisms or only used by
_KERNEL code.

sys/param.h is still fully supported and usable, but the base is
completely refactored to use the better practice (for cleanliness,
but also as a demonstration of good practice moving forward).

So in the base, only 185 includes of sys/param.h exist.  This is to
support uses of the following by programs in the base:
   1 ALIGNBYTES
   1 ALIGNED_POINTER
   1 MID_MACHINE(our own infection...)
   1 NOFILE_MAX
   2 BSD
   2 PAGE_SHIFT
   2 PZERO
   3 MACHINE_ARCH   (our own infection...)
   3 isclr
   4 MACHINE(our own infection...)
   4 clrbit
   4 powerof2
   5 dbtob
   7 btodb
   8 NODEV
  11 ALIGN
  11 setbit
  12 MAX
  12 isset
  13 nitems (our own infection...)
  14 MIN
  22 MAXCOMLEN
  23 roundup
  28 MAXBSIZE
  38 DEV_BSIZE

The inclusion of sys/param.h via netdb.h and arpa/nameser.h has
been terminated, and the ports tree was repaired (simpler than originally
thought.  10 programs?)  The most scary impact is that BSD will no
longer be defined in some enviroments which picked it up via netdb.h
or arpa/nameser.h, so we'll have to keep an eye out for such failures.

Finally, this brings us back to MIN() and MAX(), in your original
question.  There were quite a few uses of this.  To avoid the
namespace poisoning I replaced all uses with local #define's of
MINIMUM() and MAXIMUM(), and will revisit looking for other solutions
later...



Re: fread optimization

2015-01-21 Thread Loganaden Velvindron
On Wed, Jan 21, 2015 at 5:42 PM, enh e...@google.com wrote:
 On Wed, Jan 21, 2015 at 3:04 AM, Martin Pieuchot mpieuc...@nolizard.org 
 wrote:
 Hello Elliott,

 On 20/01/15(Tue) 16:15, enh wrote:
 that patch wasn't setting the _flags right on error or eof.

 Thanks!  Below is a version of your diff with some tweaks to match the
 recent changes done in -current.

 In your original post you've shown some test numbers.  Does it mean that
 you have a test program for fread(3)?  If so do you think it would fit as
 test in OpenBSD's regress framework?

 we have over a thousand C library tests and a small number of
 benchmarks in bionic/tests and bionic/benchmarks in the Android tree,
 all BSD-licensed. (though this only amounts to 42% coverage.)

 I'd suggest you to check the setup of your mail client, apparently it
 eats all the tabs and makes impossible to apply your diffs correctly :)

 afaik, there's nothing to can do to stop gmail eating tabs.

Check out devio.us if you need a shell account, to send diffs to OpenBSD.



 Index: fread.c
 ===
 RCS file: /home/ncvs/src/lib/libc/stdio/fread.c,v
 retrieving revision 1.13
 diff -u -p -r1.13 fread.c
 --- fread.c 8 Dec 2014 20:40:53 -   1.13
 +++ fread.c 21 Jan 2015 10:54:56 -
 @@ -37,18 +37,19 @@
  #include errno.h
  #include local.h

 +#define MINIMUM(a, b)  (((a)  (b)) ? (a) : (b))

 you don't want to use the MIN from sys/param.h? many files in libc
 already do. (though admittedly fvwrite.c defines its own, but that
 seems like a bug.)

  #define MUL_NO_OVERFLOW(1UL  (sizeof(size_t) * 4))

  size_t
  fread(void *buf, size_t size, size_t count, FILE *fp)
  {
 -   size_t resid;
 -   char *p;
 -   int r;
 +   size_t desired_total;
 size_t total;
 +   char *dst;

 /*
 -* Extension:  Catch integer overflow
 +* Extension:  Catch integer overflow.
  */
 if ((size = MUL_NO_OVERFLOW || count = MUL_NO_OVERFLOW) 
 size  0  SIZE_MAX / size  count) {
 @@ -57,47 +58,79 @@ fread(void *buf, size_t size, size_t cou
 return (0);
 }

 +   desired_total = count * size;
 +   total = desired_total;
 +
 /*
  * ANSI and SUSv2 require a return value of 0 if size or count are 0.
  */
 -   if ((resid = count * size) == 0)
 +   if (total == 0)
 return (0);
 +
 FLOCKFILE(fp);
 _SET_ORIENTATION(fp, -1);
 +
 +   /* XXX: how can this ever happen?! */
 if (fp-_r  0)
 fp-_r = 0;
 -   total = resid;
 -   p = buf;

 -   if ((fp-_flags  __SNBF) != 0) {
 +
 +   /*
 +* Ensure _bf._size is valid.
 +*/
 +   if (fp-_bf._base == NULL)
 +   __smakebuf(fp);
 +
 +   dst = buf;
 +
 +   while (total  0) {
 /*
 -* We know if we're unbuffered that our buffer is empty, so
 -* we can just read directly. This is much faster than the
 -* loop below which will perform a series of one byte reads.
 +* Copy data out of the buffer.
  */
 -   while (resid  0  (r = (*fp-_read)(fp-_cookie, p, 
 resid))  0) {
 -   p += r;
 -   resid -= r;
 -   }
 -   FUNLOCKFILE(fp);
 -   return ((total - resid) / size);
 +   size_t buffered_bytes = MINIMUM(fp-_r, total);
 +
 +   memcpy(dst, fp-_p, buffered_bytes);
 +   fp-_p += buffered_bytes;
 +   fp-_r -= buffered_bytes;
 +   dst += buffered_bytes;
 +   total -= buffered_bytes;
 +
 +   /*
 +* Are we done?
 +*/
 +   if (total == 0)
 +   goto out;
 +
 +   /*
 +* Do we have so much more to read that we should
 +* avoid copying it through the buffer?
 +*/
 +   if (total  (size_t) fp-_bf._size)
 +   break;
 +
 +   /*
 +* Less than a buffer to go, so refill the buffer and
 +* go around the loop again.
 +*/
 +   if (__srefill(fp))
 +   goto out;
 }

 -   while (resid  (r = fp-_r)) {
 -   (void)memcpy((void *)p, (void *)fp-_p, (size_t)r);
 -   fp-_p += r;
 -   /* fp-_r = 0 ... done in __srefill */
 -   p += r;
 -   resid -= r;
 -   if (__srefill(fp)) {
 -   /* no more input: return partial result */
 -   FUNLOCKFILE(fp);
 -   return ((total - resid) / size);
 +   /*
 +* Read directly into the caller's buffer.
 +*/
 +   while (total  0) {
 +   ssize_t bytes_read = 

Re: fread optimization

2015-01-21 Thread Ted Unangst
On Wed, Jan 21, 2015 at 12:04, Martin Pieuchot wrote:
 Hello Elliott,
 
 On 20/01/15(Tue) 16:15, enh wrote:
 that patch wasn't setting the _flags right on error or eof.
 
 Thanks!  Below is a version of your diff with some tweaks to match the
 recent changes done in -current.

fwiw, I think this is a good diff, but maybe for 5.8 and not 5.7. It
will take a while for me to be certain this is functionally equivalent.



if_media.c: #include net/if_var.h

2015-01-21 Thread Fabian Raetz
Hi,

if_media.c needs net/if_var.h. This fixes the build with IFMEDIA_DEBUG.

Regards,
Fabian


Index: sys/net/if_media.c
===
RCS file: /cvs/src/sys/net/if_media.c,v
retrieving revision 1.24
diff -u -p -r1.24 if_media.c
--- sys/net/if_media.c  9 Dec 2014 07:05:06 -   1.24
+++ sys/net/if_media.c  21 Jan 2015 22:18:29 -
@@ -84,6 +84,7 @@
 #include sys/malloc.h
 
 #include net/if.h
+#include net/if_var.h
 #include net/if_media.h
 #include net/netisr.h
 



mail(1) -r argument with mailbox

2015-01-21 Thread Martin Brandenburg
This makes mail(1) reject -r when not sending a message as it already does for
-s, -c, and -b.

I was going to write a patch to take -r with a mailbox but realized I could set
from interactively so nobody would want that.

-- Martin

Index: main.c
===
RCS file: /cvs/src/usr.bin/mail/main.c,v
retrieving revision 1.28
diff -u -p -r1.28 main.c
--- main.c  20 Jan 2015 16:59:07 -  1.28
+++ main.c  21 Jan 2015 22:57:51 -
@@ -185,8 +185,10 @@ main(int argc, char **argv)
/*
 * Check for inconsistent arguments.
 */
-   if (to == NULL  (subject != NULL || cc != NULL || bcc != NULL))
-   errx(1, You must specify direct recipients with -s, -c, or 
-b);
+   if (to == NULL  (subject != NULL || cc != NULL || bcc != NULL ||
+   fromaddr != NULL))
+   errx(1, You must specify direct recipients with -s, -c, -b, 
+   or -r);
/*
 * Block SIGINT except where we install an explicit handler for it.
 */



Re: enable jumbos on newer re(4) devices

2015-01-21 Thread David Gwynne

 On 21 Jan 2015, at 23:49, Brad Smith b...@comstyle.com wrote:
 
 On 01/21/15 06:51, Jim Smith wrote:
 hi all,
 
 the below diff enables support for jumbo frames on
 some newer re(4) devices. i've tested it on 8186D/8111D
 and 8186E/8111E chips, which are both able to do 9k
 jumbos. it seems to provide a significant speed-up on
 simple file transfer tests. most of the important parts
 were taken from the freebsd re(4) driver.
 
 feedback welcome, hope this helps someone.
 
 I had started looking into adding support for jumbos to re(4)
 but what I have so far does not work; no crashing but the
 interface does not receive any packets. What you posted still
 needs some work. I'll see if I can get back to it soon-ish but
 I have put it aside as it was not intended to be a priority for
 the next release.

thats not very constructive feedback, especially if you dont have to time to 
tweak the code.

if you could explain what needs work, maybe jim could have a go at it. he's 
already spent the time to get it this far, and he said feedback is welcome.

dlg




Re: Fewer malloc() memcpy() in USB land

2015-01-21 Thread David Higgs
On Fri, Jan 9, 2015 at 2:07 PM, Martin Pieuchot mpieuc...@nolizard.org wrote:
 On 09/01/15(Fri) 12:36, David Higgs wrote:
 On Fri, Jan 9, 2015 at 9:00 AM, Martin Pieuchot mpieuc...@nolizard.org 
 wrote:
  As pointed out by David Higgs, uhidev report functions do a lot of
  memory allocations and copies between buffers.  This is not uncommon
  in USB land due to way DMA buffers are handled.
 
  One way to reduce the number of copies is to submit a transfer with
  the USBD_NO_COPY flag.  Without it the kernel does two to three copies:
 
(stack/driver array --) malloc'ed array -- DMA reacheable array
 
  This is not limited to uhidev functions.  That's also done for every
  transfer sent through an interrupt pipe or for every control request
  with data.
 
  I'd like to slowly change the stack such that USBD_NO_COPY becomes the
  default behavior.  This would first reduces the number of buffer copies
  and then allow umass(4) to directly use the DMA reachable buffers
  provided by the SCSI stack, which should *at least* reduce the CPU usage
  when using USB drives.
 
  Here's a diff about uhidev(4) to illustrate the changes I'm talking
  about.
 
  Comments, ok?
 

 See inline.  Reviewed to the best of my ability/eyesight via
 variable-width webmail.
 [...]
  +
  +   if (id  0)
  +   len++;
  +
  +   buf = usbd_alloc_buffer(xfer, len);
  +   if (buf == NULL)
  +   return (-1);

 You forgot to free xfer in this error path.

 Indeed!

  @@ -586,6 +585,7 @@ usbd_status
   usbd_clear_endpoint_stall_async(struct usbd_pipe *pipe)
   {
  struct usbd_device *dev = pipe-device;
  +   struct usbd_xfer *xfer;
  usb_device_request_t req;
  usbd_status err;
 
  @@ -596,7 +596,12 @@ usbd_clear_endpoint_stall_async(struct u
  USETW(req.wValue, UF_ENDPOINT_HALT);
  USETW(req.wIndex, pipe-endpoint-edesc-bEndpointAddress);
  USETW(req.wLength, 0);
  -   err = usbd_do_request_async(dev, req, 0, 0, 0);
  +
  +   xfer = usbd_alloc_xfer(dev);
  +   if (xfer == NULL)
  +   return (USBD_NOMEM);
  +
  +   err = usbd_request_async(xfer, req, NULL, NULL);

 Missing xfer cleanup here too, I think.

 Here it's fine, as soon as you call usbd_request_async() the xfer will be
 freed.

 Updated diff below.


The updated diff appears to works for me and I don't see any further
issues upon review.  No behavior changes when applied to a snapshot +
HEAD kernel as of this evening.  Tested via repeated sysctl reads of
upd(4) sensor info and a few device detach/attach events.

--david



Re: fread optimization

2015-01-21 Thread Martin Pieuchot
Hello Elliott,

On 20/01/15(Tue) 16:15, enh wrote:
 that patch wasn't setting the _flags right on error or eof.

Thanks!  Below is a version of your diff with some tweaks to match the
recent changes done in -current.

In your original post you've shown some test numbers.  Does it mean that
you have a test program for fread(3)?  If so do you think it would fit as
test in OpenBSD's regress framework?

I'd suggest you to check the setup of your mail client, apparently it
eats all the tabs and makes impossible to apply your diffs correctly :)

Index: fread.c
===
RCS file: /home/ncvs/src/lib/libc/stdio/fread.c,v
retrieving revision 1.13
diff -u -p -r1.13 fread.c
--- fread.c 8 Dec 2014 20:40:53 -   1.13
+++ fread.c 21 Jan 2015 10:54:56 -
@@ -37,18 +37,19 @@
 #include errno.h
 #include local.h
 
+#define MINIMUM(a, b)  (((a)  (b)) ? (a) : (b))
+
 #define MUL_NO_OVERFLOW(1UL  (sizeof(size_t) * 4))
 
 size_t
 fread(void *buf, size_t size, size_t count, FILE *fp)
 {
-   size_t resid;
-   char *p;
-   int r;
+   size_t desired_total;
size_t total;
+   char *dst;
 
/*
-* Extension:  Catch integer overflow
+* Extension:  Catch integer overflow.
 */
if ((size = MUL_NO_OVERFLOW || count = MUL_NO_OVERFLOW) 
size  0  SIZE_MAX / size  count) {
@@ -57,47 +58,79 @@ fread(void *buf, size_t size, size_t cou
return (0);
}
 
+   desired_total = count * size;
+   total = desired_total;
+
/*
 * ANSI and SUSv2 require a return value of 0 if size or count are 0.
 */
-   if ((resid = count * size) == 0)
+   if (total == 0)
return (0);
+
FLOCKFILE(fp);
_SET_ORIENTATION(fp, -1);
+
+   /* XXX: how can this ever happen?! */
if (fp-_r  0)
fp-_r = 0;
-   total = resid;
-   p = buf;
 
-   if ((fp-_flags  __SNBF) != 0) {
+
+   /*
+* Ensure _bf._size is valid.
+*/
+   if (fp-_bf._base == NULL)
+   __smakebuf(fp);
+
+   dst = buf;
+
+   while (total  0) {
/*
-* We know if we're unbuffered that our buffer is empty, so
-* we can just read directly. This is much faster than the
-* loop below which will perform a series of one byte reads.
+* Copy data out of the buffer.
 */
-   while (resid  0  (r = (*fp-_read)(fp-_cookie, p, resid))  
0) {
-   p += r;
-   resid -= r;
-   }
-   FUNLOCKFILE(fp);
-   return ((total - resid) / size);
+   size_t buffered_bytes = MINIMUM(fp-_r, total);
+
+   memcpy(dst, fp-_p, buffered_bytes);
+   fp-_p += buffered_bytes;
+   fp-_r -= buffered_bytes;
+   dst += buffered_bytes;
+   total -= buffered_bytes;
+
+   /*
+* Are we done?
+*/
+   if (total == 0)
+   goto out;
+
+   /*
+* Do we have so much more to read that we should
+* avoid copying it through the buffer?
+*/
+   if (total  (size_t) fp-_bf._size)
+   break;
+
+   /*
+* Less than a buffer to go, so refill the buffer and
+* go around the loop again.
+*/
+   if (__srefill(fp))
+   goto out;
}
 
-   while (resid  (r = fp-_r)) {
-   (void)memcpy((void *)p, (void *)fp-_p, (size_t)r);
-   fp-_p += r;
-   /* fp-_r = 0 ... done in __srefill */
-   p += r;
-   resid -= r;
-   if (__srefill(fp)) {
-   /* no more input: return partial result */
-   FUNLOCKFILE(fp);
-   return ((total - resid) / size);
+   /*
+* Read directly into the caller's buffer.
+*/
+   while (total  0) {
+   ssize_t bytes_read = (*fp-_read)(fp-_cookie, dst, total);
+
+   if (bytes_read = 0) {
+   fp-_flags = (fp-_r == 0) ? __SEOF : __SERR;
+   break;
}
+   dst += bytes_read;
+   total -= bytes_read;
}
-   (void)memcpy((void *)p, (void *)fp-_p, resid);
-   fp-_r -= resid;
-   fp-_p += resid;
+
+out:
FUNLOCKFILE(fp);
-   return (count);
+   return ((desired_total - total) / size);
 }



enable jumbos on newer re(4) devices

2015-01-21 Thread Jim Smith
hi all,

the below diff enables support for jumbo frames on
some newer re(4) devices. i've tested it on 8186D/8111D
and 8186E/8111E chips, which are both able to do 9k
jumbos. it seems to provide a significant speed-up on
simple file transfer tests. most of the important parts
were taken from the freebsd re(4) driver.

feedback welcome, hope this helps someone.

cheers,
jim

Index: re.c
===
RCS file: /cvs/src/sys/dev/ic/re.c,v
retrieving revision 1.173
diff -u -r1.173 re.c
--- re.c21 Jan 2015 10:00:42 -  1.173
+++ re.c21 Jan 2015 11:10:31 -
@@ -171,6 +171,8 @@
 intre_ifmedia_upd(struct ifnet *);
 void   re_ifmedia_sts(struct ifnet *, struct ifmediareq *);
 
+void   re_set_jumbo(struct rl_softc *);
+
 void   re_eeprom_putbyte(struct rl_softc *, int);
 void   re_eeprom_getword(struct rl_softc *, int, u_int16_t *);
 void   re_read_eeprom(struct rl_softc *, caddr_t, int, int);
@@ -206,6 +208,10 @@
CSR_WRITE_1(sc, RL_EECMD,   \
CSR_READ_1(sc, RL_EECMD)  ~x)
 
+#define RL_FRAMELEN(mtu)   \
+   (mtu + ETHER_HDR_LEN + ETHER_CRC_LEN +  \
+   ETHER_VLAN_ENCAP_LEN)
+
 static const struct re_revision {
u_int32_t   re_chipid;
const char  *re_name;
@@ -1022,8 +1028,10 @@
 
/* Create DMA maps for RX buffers */
for (i = 0; i  RL_RX_DESC_CNT; i++) {
-   error = bus_dmamap_create(sc-sc_dmat, MCLBYTES, 1, MCLBYTES,
-   0, 0, sc-rl_ldata.rl_rxsoft[i].rxs_dmamap);
+   error = bus_dmamap_create(sc-sc_dmat,
+   RL_FRAMELEN(sc-rl_max_mtu), 1,
+   RL_FRAMELEN(sc-rl_max_mtu), 0, 0,
+   sc-rl_ldata.rl_rxsoft[i].rxs_dmamap);
if (error) {
printf(%s: can't create DMA map for RX\n,
sc-sc_dev.dv_xname);
@@ -1038,8 +1046,7 @@
ifp-if_ioctl = re_ioctl;
ifp-if_start = re_start;
ifp-if_watchdog = re_watchdog;
-   if ((sc-rl_flags  RL_FLAG_JUMBOV2) == 0)
-   ifp-if_hardmtu = sc-rl_max_mtu;
+   ifp-if_hardmtu = sc-rl_max_mtu;
IFQ_SET_MAXLEN(ifp-if_snd, RL_TX_QLEN);
IFQ_SET_READY(ifp-if_snd);
 
@@ -1159,7 +1166,7 @@
u_int32_t   cmdstat;
int error, idx;
 
-   m = MCLGETI(NULL, M_DONTWAIT, NULL, MCLBYTES);
+   m = MCLGETI(NULL, M_DONTWAIT, NULL, RL_FRAMELEN(sc-rl_max_mtu));
if (!m)
return (ENOBUFS);
 
@@ -1168,7 +1175,7 @@
 * alignment so that the frame payload is
 * longword aligned on strict alignment archs.
 */
-   m-m_len = m-m_pkthdr.len = RE_RX_DESC_BUFLEN;
+   m-m_len = m-m_pkthdr.len = RL_FRAMELEN(sc-rl_max_mtu);
m-m_data += RE_ETHER_ALIGN;
 
idx = sc-rl_ldata.rl_rx_prodidx;
@@ -1274,7 +1281,7 @@
 {
struct mbuf *m;
struct ifnet*ifp;
-   int i, total_len, rx = 0;
+   int i, total_len, rxerr, rx = 0;
struct rl_desc  *cur_rx;
struct rl_rxsoft *rxs;
u_int32_t   rxstat, rxvlan;
@@ -1306,8 +1313,12 @@
BUS_DMASYNC_POSTREAD);
bus_dmamap_unload(sc-sc_dmat, rxs-rxs_dmamap);
 
-   if (!(rxstat  RL_RDESC_STAT_EOF)) {
-   m-m_len = RE_RX_DESC_BUFLEN;
+   if ((sc-rl_flags  RL_FLAG_JUMBOV2) != 0 
+   (rxstat  (RL_RDESC_STAT_SOF | RL_RDESC_STAT_EOF)) !=
+   (RL_RDESC_STAT_SOF | RL_RDESC_STAT_EOF)) {
+   continue;
+   } else if (!(rxstat  RL_RDESC_STAT_EOF)) {
+   m-m_len = RL_FRAMELEN(sc-rl_max_mtu);
if (sc-rl_head == NULL)
sc-rl_head = sc-rl_tail = m;
else {
@@ -1341,24 +1352,31 @@
 * if total_len  2^13-1, both _RXERRSUM and _GIANT will be
 * set, but if CRC is clear, it will still be a valid frame.
 */
-   if (rxstat  RL_RDESC_STAT_RXERRSUM  !(total_len  8191 
-   (rxstat  RL_RDESC_STAT_ERRS) == RL_RDESC_STAT_GIANT)) {
-   ifp-if_ierrors++;
-   /*
-* If this is part of a multi-fragment packet,
-* discard all the pieces.
-*/
-   if (sc-rl_head != NULL) {
-   m_freem(sc-rl_head);
-   sc-rl_head = sc-rl_tail = NULL;
+   if ((rxstat  RL_RDESC_STAT_RXERRSUM) != 0) {
+   rxerr = 1; 
+   if (rxstat  RL_RDESC_STAT_RXERRSUM  !(total_len  
8191 
+  (rxstat  RL_RDESC_STAT_ERRS) == 
RL_RDESC_STAT_GIANT)) {
+   rxerr 

Re: cdce(4) and MBIM

2015-01-21 Thread Gerhard Roth
Hi Ingo,

sorry to disappoint you, but that won't work. First of all, if_cdce.c doesn't
do NCM encoding and second, even if it did this still wouldn't work because
it just describes how data packets are encapsulated. But to talk to an MBIM
device, you need a different set of control messages (e.g. to set the PIN,
to tell the device to connect to the network, etc.)

I'm currently working on an MBIM driver for OpenBSD, but it will take some
more time until it's ready for sending out patches.

Gerhard


On Tue, 20 Jan 2015 23:31:17 +0100 Ingo Feinerer feine...@logic.at wrote:
 Has anyone experiences with USB devices (e.g. UMTS modem) offering
 Mobile Broadband Interface Model (MBIM) interfaces?
 
 According to
 www.usb.org/developers/docs/devclass_docs/MBIM10Errata1_073013.zip MBIM
 is comparable to NCM (The largest deviation from NCM 1.0 is that
 devices transfer raw IP packets instead of packets with 802.3 headers.)
 which is supported by cdce(4).
 
 By hardcoding vendor and device ID in sys/dev/usb/if_cdce.c I managed to
 have a modem with MBIM interface attach via cdce:
 
 cdce0 at uhub0 port 4 configuration 1 interface 0 MediaTek Inc Product rev 
 2.00/3.00 addr 2
 cdce0: address XX:XX:XX:XX:XX:XX
 
 ifconfig appears to work as well
 
 cdce0: flags=8802BROADCAST,SIMPLEX,MULTICAST mtu 1500
 lladdr XX:XX:XX:XX:XX:XX
 priority: 0
 
 but dhclient gets no response. /var/log/messages contains
 
 cdce0: watchdog timeout
 cdce0: usb error on tx: TIMEOUT
 
 Any ideas?
 
 Best regards,
 Ingo
 



Re: Use rtdeletemsg()

2015-01-21 Thread Martin Pieuchot
On 19/01/15(Mon) 09:35, Todd C. Miller wrote:
 On Mon, 19 Jan 2015 11:49:53 +0100, Martin Pieuchot wrote:
 
  Instead of rerolling rtrequest1(RTM_DELETE...) code in various places,
  simply use rtdeletemsg() which also notify userland that the route entry
  is going away.
 
 Since rtdeletemsg() may call rtfree() doesn't this mean that we can
 end up calling rtfree() twice?  Or is rt-rt_refcnt never going to
 be zero in this case?

It is indeed confusing.  I tried to check every cases but in the end I 
think that it might be better to decouple the removal from the routing
table and the rtfree().  Updated diff below does that.

Another advantage I can see to this approach is to be more strict about
the reference counter on a per-rt basic.

Index: net/route.c
===
RCS file: /home/ncvs/src/sys/net/route.c,v
retrieving revision 1.200
diff -u -p -r1.200 route.c
--- net/route.c 18 Jan 2015 14:51:43 -  1.200
+++ net/route.c 21 Jan 2015 12:17:21 -
@@ -544,11 +544,6 @@ rtdeletemsg(struct rtentry *rt, u_int ta
 
rt_missmsg(RTM_DELETE, info, info.rti_flags, ifp, error, tableid);
 
-   /* Adjust the refcount */
-   if (error == 0  rt-rt_refcnt = 0) {
-   rt-rt_refcnt++;
-   rtfree(rt);
-   }
return (error);
 }
 
@@ -556,11 +551,19 @@ int
 rtflushclone1(struct radix_node *rn, void *arg, u_int id)
 {
struct rtentry  *rt, *parent;
+   int error;
 
rt = (struct rtentry *)rn;
parent = (struct rtentry *)arg;
-   if ((rt-rt_flags  RTF_CLONED) != 0  rt-rt_parent == parent)
-   rtdeletemsg(rt, id);
+   if ((rt-rt_flags  RTF_CLONED) != 0  rt-rt_parent == parent) {
+   error = rtdeletemsg(rt, id);
+
+   /* Adjust the refcount */
+   if (error == 0  rt-rt_refcnt = 0) {
+   rt-rt_refcnt++;
+   rtfree(rt);
+   }
+   }
return 0;
 }
 
@@ -1632,8 +1635,17 @@ rt_if_remove_rtdelete(struct radix_node 
if (rt-rt_ifp == ifp) {
int cloning = (rt-rt_flags  RTF_CLONING);
 
-   if (rtdeletemsg(rt, id) == 0  cloning)
-   return (EAGAIN);
+   if (rtdeletemsg(rt, id) == 0) {
+
+   /* Adjust the refcount */
+   if (rt-rt_refcnt = 0) {
+   rt-rt_refcnt++;
+   rtfree(rt);
+   }
+
+   if (cloning)
+   return (EAGAIN);
+   }
}
 
/*
Index: netinet/if_ether.c
===
RCS file: /home/ncvs/src/sys/netinet/if_ether.c,v
retrieving revision 1.141
diff -u -p -r1.141 if_ether.c
--- netinet/if_ether.c  13 Jan 2015 12:16:18 -  1.141
+++ netinet/if_ether.c  21 Jan 2015 12:17:21 -
@@ -789,6 +789,7 @@ arptfree(struct llinfo_arp *la)
struct rtentry *rt = la-la_rt;
struct sockaddr_dl *sdl;
u_int tid = 0;
+   int error;
 
if (rt == NULL)
panic(arptfree);
@@ -803,7 +804,13 @@ arptfree(struct llinfo_arp *la)
if (rt-rt_ifp)
tid = rt-rt_ifp-if_rdomain;
 
-   rtdeletemsg(rt, tid);
+   error = rtdeletemsg(rt, tid);
+
+   /* Adjust the refcount */
+   if (error == 0  rt-rt_refcnt = 0) {
+   rt-rt_refcnt++;
+   rtfree(rt);
+   }
 }
 
 /*
Index: netinet/ip_icmp.c
===
RCS file: /home/ncvs/src/sys/netinet/ip_icmp.c,v
retrieving revision 1.129
diff -u -p -r1.129 ip_icmp.c
--- netinet/ip_icmp.c   22 Dec 2014 11:05:53 -  1.129
+++ netinet/ip_icmp.c   21 Jan 2015 12:17:21 -
@@ -1031,20 +1031,12 @@ icmp_mtudisc_timeout(struct rtentry *rt,
(RTF_DYNAMIC | RTF_HOST)) {
void *(*ctlfunc)(int, struct sockaddr *, u_int, void *);
struct sockaddr_in sa;
-   struct rt_addrinfo info;
int s;
 
-   memset(info, 0, sizeof(info));
-   info.rti_info[RTAX_DST] = rt_key(rt);
-   info.rti_info[RTAX_NETMASK] = rt_mask(rt);
-   info.rti_info[RTAX_GATEWAY] = rt-rt_gateway;
-   info.rti_flags = rt-rt_flags;   
-
sa = *(struct sockaddr_in *)rt_key(rt);
 
s = splsoftnet();
-   rtrequest1(RTM_DELETE, info, rt-rt_priority, NULL,
-   r-rtt_tableid);
+   rtdeletemsg(rt, r-rtt_tableid);
 
/* Notify TCP layer of increased Path MTU estimate */
ctlfunc = inetsw[ip_protox[IPPROTO_TCP]].pr_ctlinput;
@@ -1083,18 +1075,10 @@ icmp_redirect_timeout(struct rtentry *rt
 
if ((rt-rt_flags  (RTF_DYNAMIC | RTF_HOST)) ==
(RTF_DYNAMIC | RTF_HOST)) {
-   struct rt_addrinfo