Is it safe to recieve Econet data into MBUFS?
Alan Williams (2601) 97 posts |
I am hunting an insidious bug in a DCI4 version of the DCI2/RISCiX ip over Econet encapsulation and it crossed my mind to wonder if the mbuf manager moves data that its managing about in the background while adjusting the struct mbuf fields to match. Thus the client’s view of the data remains the same but the locations that its stored at could change without warning. Since I am receiving Econet data into MBUFS this could be a bad thing. The insidious bit is the bug is packet size dependent, normal ping is ok, ping with 1024 bytes and its bye bye machine. The damage seems to get done receiving the packet though it doesn’t manifest until freeing the reply. The pinging machine will receive the reply and say 0% packet loss but the target will be stone dead by now. Things like telnet are fine as is pcnfsd and nfs v2 mount but opening the filer window & its stone dead again. If anybody knows if receiving Econet into mbufs is safe or not that would usefully rule one thing in or out. |
Sprow (202) 1164 posts |
If you allocated the mbuf, and it’s a safe mbuf, then that memory is yours until freed. MBufManager doesn’t move stuff under your feet. Even an ‘unsafe’ mbuf would be OK from the point of view as a driver, the distinction of safe versus unsafe only matters to the protocol module.
Are you making an assumption that the memory is contiguous within the mbuf? Unless specifically forced contiguous a request for 1024 bytes could be returned at 1000+24 or 4×256 or whatever, so if you cast that pointer and copy 1024 bytes into it the tail end would overwrite some other data which would blow up in all kinds of ways depending on what that RMA happened to contain. |
Alan Williams (2601) 97 posts |
I had that in mind, this is a bit of my transmit swi, for addressed ip frames. size=(mm.count_bytes)(&mm,(struct mbuf)r→r3); (mm.ensure_safe)(&mm,(struct mbuf)r→r3); The odd thing is that the problem went a way when I commented out the last line and stopped calling the mbuf manger to ensure the mbuf chain from the protocol was contiguous. I am writing against the DCI-4 Functional spec Issue 3, 26 August 1999. I could not immediately find any reference to this document on this site and I wondered if anybody knew of a newer version. I would like to see if mm.ensure_contig is described any differently in newer versions. Another interesting mistake a made was to install an event handler for econet events and to convert them to callbacks and the do all the work in the callback. It worked really well for telnet I could telnet RISC iX and do find / -ls and that worked without a hitch. !Nettle being a desktop app provided plenty of times for the callback to run. Firing up NFS highlighted the problem though fileystems don’t return to user mode and so none of my deferred events got run. OK live an learn. Now I am carefully trying to rework my code directly into the event handlers. I have been using the DADebug module to trap and view debug output but that’s not so good when things crash so now if that’s not loaded my code falls back to driving the UART directly in polled mode and sending all debug messages out the serial port. (I should have done this years ago) Unfortunately the project has hit another relatively severe snag, My A540, which has been serving as either DCI2 RISC OS peer or RISC iX refused to boot today. Emitting only a single line of garbled message trans tokens relating to aborts and exceptions at 0×0. My A4 is similarly striken and in a pile of bits at the moment too. Pulling the A540 to bits now…. |
Rick Murray (539) 13958 posts |
If I remember correctly, there’s a build of DADebug that can output to serial port (but it might need the HAL debug port setting active (on RO5)?). |
Alan Williams (2601) 97 posts |
Interesting, I will have a look for that when I go back to Pi Econet, its going to need gpio interrupts which will be treacherous to debug. |
Alan Williams (2601) 97 posts |
After further debugging I can say that I can’t get (mm.ensure_contig) to do anything other than free the mbuf chain I pass it and return zero. For now I am working round this by creating a new single mbuf of the same size as the chain from the protocol and exporting the chain to the new mbuf. I am then freeing the chain from the stack and continuing on with the single mbuf that Econet can TX from. Now all processing has moved directly into the event threads and NFS from my RPC to RISCiX over econet is working. Next it will be moving back to my Pi, where I aim to make it work too. There is potential to put ipv6 over econet as well. I am also wondering about implementing the DCI4 IP over econet encapsulation in the same module, but I have no documentation and no idea what it was ever used for and there should be an EconetA module that does this on its own. |