[En-Nut-Discussion] ARP cache again

Dusan Ferbas dferbas at dfsoft.cz
Sat Feb 19 13:38:48 CET 2005


Hi Harald,

after discussing with Marek Pavlu we pointed out several possibilities for 
ARP deadlock (not only when Nut/OS works as a client).

NutArpCacheQuery()
--------------------
- NutArpOutput() can release netbuf if there is no heap for a link buffer 
or if too large packet is attempted to send with RTL driver
         (see net/ethout.c:NutEtherOutput() or dev/nicrtl.c:NicOutput(), -1 
is returned )

         if (retries-- == 0) || (nb && NutArpOutput(dev, nb))) {
             break;
         }
-> (I suggest to change to:)
         if (retries-- == 0)
             break;
         if (nb && NutArpOutput(dev, nb)) {
             nb = 0;                             //<<added: mark buffer was 
released
             break;
         }


- I do not know if it really can occure but it can happen that during a 
wait ARP entry can be released
     if (nb) {
         NutNetBufFree(nb);
         if (rc && entry) {                      //<< added entry check
             entry->ae_flags |= ATF_REM;
             ArpCacheFlush(ifn);
         }
     }

- if 2nd thread is waiting for an ARP entry completion and 1st thread 
removes that entry, then 2nd thread is locked forever

I suggest to announce such an ARP entry release in ArpCacheFlush():

             *aep = ae->ae_next;
             free(ae);
             NutEventBroadcast(&ae->ae_tq);      //<< added to release 
other possibly waiting thread(s)


- also at the beginning of NutArpCacheQuery if there is no heap for netbuf 
ARP entry will stay allocated and it will take 10 minutes to  get rid of it
(if intension is to keep ARP entry allocated for next usage then I suggest 
to comment it here:
 >> here if there is no heap for netbuf, ARP entry remains allocated and 
waits until it ages out or it is used again.
)

     if ((entry = ArpCacheLookup(ifn, ip)) == 0) {
         if ((entry = ArpCacheNew(ifn, ip, 0)) == 0) {
             return -1;
         }
         if ((nb = NutArpAllocNetBuf(ARPOP_REQUEST, ip, 0)) == 0) {
             //<< release ARP entry (personally I vote for goto here)
             return -1;
         }
     }


Dusan 




More information about the En-Nut-Discussion mailing list