2012/12/11 Matthias Brugger <[email protected]>: > This patch tackles the time out problem which leads to break the > boot process, when loading file over nfs. The patch does two things. > > First of all, we just ignore messages that arrive with a rpc_id smaller > then the client id. We just interpret this messages as answers to > formaly timed out messages. > > Second, when a time out occurs we double the time to wait, so that we > do not stress the server resending the last message.
Any comment on the patch? > > Signed-off-by: Matthias Brugger <[email protected]> > --- > net/nfs.c | 73 > +++++++++++++++++++++++++++++++++++++++++++------------------ > 1 file changed, 52 insertions(+), 21 deletions(-) > > diff --git a/net/nfs.c b/net/nfs.c > index 7f2393f..84aeda1 100644 > --- a/net/nfs.c > +++ b/net/nfs.c > @@ -37,10 +37,14 @@ > # define NFS_TIMEOUT CONFIG_NFS_TIMEOUT > #endif > > +#define NFS_RPC_ERR 1 > +#define NFS_RPC_DROP 124 > + > static int fs_mounted; > static unsigned long rpc_id; > static int nfs_offset = -1; > static int nfs_len; > +static ulong nfs_timeout = NFS_TIMEOUT; > > static char dirfh[NFS_FHSIZE]; /* file handle of directory */ > static char filefh[NFS_FHSIZE]; /* file handle of kernel image */ > @@ -399,8 +403,10 @@ rpc_lookup_reply(int prog, uchar *pkt, unsigned len) > > debug("%s\n", __func__); > > - if (ntohl(rpc_pkt.u.reply.id) != rpc_id) > - return -1; > + if (ntohl(rpc_pkt.u.reply.id) > rpc_id) > + return -NFS_RPC_ERR; > + else if (ntohl(rpc_pkt.u.reply.id) < rpc_id) > + return -NFS_RPC_DROP; > > if (rpc_pkt.u.reply.rstatus || > rpc_pkt.u.reply.verifier || > @@ -428,8 +434,10 @@ nfs_mount_reply(uchar *pkt, unsigned len) > > memcpy((unsigned char *)&rpc_pkt, pkt, len); > > - if (ntohl(rpc_pkt.u.reply.id) != rpc_id) > - return -1; > + if (ntohl(rpc_pkt.u.reply.id) > rpc_id) > + return -NFS_RPC_ERR; > + else if (ntohl(rpc_pkt.u.reply.id) < rpc_id) > + return -NFS_RPC_DROP; > > if (rpc_pkt.u.reply.rstatus || > rpc_pkt.u.reply.verifier || > @@ -452,8 +460,10 @@ nfs_umountall_reply(uchar *pkt, unsigned len) > > memcpy((unsigned char *)&rpc_pkt, pkt, len); > > - if (ntohl(rpc_pkt.u.reply.id) != rpc_id) > - return -1; > + if (ntohl(rpc_pkt.u.reply.id) > rpc_id) > + return -NFS_RPC_ERR; > + else if (ntohl(rpc_pkt.u.reply.id) < rpc_id) > + return -NFS_RPC_DROP; > > if (rpc_pkt.u.reply.rstatus || > rpc_pkt.u.reply.verifier || > @@ -475,8 +485,10 @@ nfs_lookup_reply(uchar *pkt, unsigned len) > > memcpy((unsigned char *)&rpc_pkt, pkt, len); > > - if (ntohl(rpc_pkt.u.reply.id) != rpc_id) > - return -1; > + if (ntohl(rpc_pkt.u.reply.id) > rpc_id) > + return -NFS_RPC_ERR; > + else if (ntohl(rpc_pkt.u.reply.id) < rpc_id) > + return -NFS_RPC_DROP; > > if (rpc_pkt.u.reply.rstatus || > rpc_pkt.u.reply.verifier || > @@ -499,8 +511,10 @@ nfs_readlink_reply(uchar *pkt, unsigned len) > > memcpy((unsigned char *)&rpc_pkt, pkt, len); > > - if (ntohl(rpc_pkt.u.reply.id) != rpc_id) > - return -1; > + if (ntohl(rpc_pkt.u.reply.id) > rpc_id) > + return -NFS_RPC_ERR; > + else if (ntohl(rpc_pkt.u.reply.id) < rpc_id) > + return -NFS_RPC_DROP; > > if (rpc_pkt.u.reply.rstatus || > rpc_pkt.u.reply.verifier || > @@ -534,8 +548,10 @@ nfs_read_reply(uchar *pkt, unsigned len) > > memcpy((uchar *)&rpc_pkt, pkt, sizeof(rpc_pkt.u.reply)); > > - if (ntohl(rpc_pkt.u.reply.id) != rpc_id) > - return -1; > + if (ntohl(rpc_pkt.u.reply.id) > rpc_id) > + return -NFS_RPC_ERR; > + else if (ntohl(rpc_pkt.u.reply.id) < rpc_id) > + return -NFS_RPC_DROP; > > if (rpc_pkt.u.reply.rstatus || > rpc_pkt.u.reply.verifier || > @@ -574,7 +590,7 @@ NfsTimeout(void) > NetStartAgain(); > } else { > puts("T "); > - NetSetTimeout(NFS_TIMEOUT, NfsTimeout); > + NetSetTimeout(nfs_timeout + NFS_TIMEOUT * NfsTimeoutCount, > NfsTimeout); > NfsSend(); > } > } > @@ -583,6 +599,7 @@ static void > NfsHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, unsigned > len) > { > int rlen; > + int reply; > > debug("%s\n", __func__); > > @@ -591,19 +608,24 @@ NfsHandler(uchar *pkt, unsigned dest, IPaddr_t sip, > unsigned src, unsigned len) > > switch (NfsState) { > case STATE_PRCLOOKUP_PROG_MOUNT_REQ: > - rpc_lookup_reply(PROG_MOUNT, pkt, len); > + if (rpc_lookup_reply(PROG_MOUNT, pkt, len) == -NFS_RPC_DROP) > + break; > NfsState = STATE_PRCLOOKUP_PROG_NFS_REQ; > NfsSend(); > break; > > case STATE_PRCLOOKUP_PROG_NFS_REQ: > - rpc_lookup_reply(PROG_NFS, pkt, len); > + if (rpc_lookup_reply(PROG_NFS, pkt, len) == -NFS_RPC_DROP) > + break; > NfsState = STATE_MOUNT_REQ; > NfsSend(); > break; > > case STATE_MOUNT_REQ: > - if (nfs_mount_reply(pkt, len)) { > + reply = nfs_mount_reply(pkt, len); > + if (reply == -NFS_RPC_DROP) > + break; > + else if (reply == -NFS_RPC_ERR) { > puts("*** ERROR: Cannot mount\n"); > /* just to be sure... */ > NfsState = STATE_UMOUNT_REQ; > @@ -615,7 +637,10 @@ NfsHandler(uchar *pkt, unsigned dest, IPaddr_t sip, > unsigned src, unsigned len) > break; > > case STATE_UMOUNT_REQ: > - if (nfs_umountall_reply(pkt, len)) { > + reply = nfs_umountall_reply(pkt, len); > + if (reply == -NFS_RPC_DROP) > + break; > + else if (reply == -NFS_RPC_ERR) { > puts("*** ERROR: Cannot umount\n"); > net_set_state(NETLOOP_FAIL); > } else { > @@ -625,7 +650,10 @@ NfsHandler(uchar *pkt, unsigned dest, IPaddr_t sip, > unsigned src, unsigned len) > break; > > case STATE_LOOKUP_REQ: > - if (nfs_lookup_reply(pkt, len)) { > + reply = nfs_lookup_reply(pkt, len); > + if (reply == -NFS_RPC_DROP) > + break; > + else if (reply == -NFS_RPC_ERR) { > puts("*** ERROR: File lookup fail\n"); > NfsState = STATE_UMOUNT_REQ; > NfsSend(); > @@ -638,7 +666,10 @@ NfsHandler(uchar *pkt, unsigned dest, IPaddr_t sip, > unsigned src, unsigned len) > break; > > case STATE_READLINK_REQ: > - if (nfs_readlink_reply(pkt, len)) { > + reply = nfs_readlink_reply(pkt, len); > + if (reply == -NFS_RPC_DROP) > + break; > + else if (reply == -NFS_RPC_ERR) { > puts("*** ERROR: Symlink fail\n"); > NfsState = STATE_UMOUNT_REQ; > NfsSend(); > @@ -654,7 +685,7 @@ NfsHandler(uchar *pkt, unsigned dest, IPaddr_t sip, > unsigned src, unsigned len) > > case STATE_READ_REQ: > rlen = nfs_read_reply(pkt, len); > - NetSetTimeout(NFS_TIMEOUT, NfsTimeout); > + NetSetTimeout(nfs_timeout, NfsTimeout); > if (rlen > 0) { > nfs_offset += rlen; > NfsSend(); > @@ -738,7 +769,7 @@ NfsStart(void) > printf("\nLoad address: 0x%lx\n" > "Loading: *\b", load_addr); > > - NetSetTimeout(NFS_TIMEOUT, NfsTimeout); > + NetSetTimeout(nfs_timeout, NfsTimeout); > net_set_udp_handler(NfsHandler); > > NfsTimeoutCount = 0; > -- > 1.7.9.5 > Hi Joe and Wolfgang, any comment on this? Best regards, Matthias -- --- motzblog.wordpress.com _______________________________________________ U-Boot mailing list [email protected] http://lists.denx.de/mailman/listinfo/u-boot

