Re: 2.6.24-rc3: find complains about /proc/net
On 11/21/07, Ingo Molnar <[EMAIL PROTECTED]> wrote: > i guess it was a v2.6.24 change, hence a regression that needs to be > fixed? It seems to be http://git.kernel.org/?p=linux/kernel/git/tglx/history.git;a=commitdiff;h=01660410 So, linux 2.6.0-test6 -- Guillaume - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH] proc: Fix the threaded /proc/self.
Hello Eric, This fills a need I had to get the current TID in a Java program, so I'm very interested in this change. OTOH, how will someone not reading LKML discover that the current TID is now in /proc/self and that it was not always the case? I would put my 2 cents in /proc/self/task/self, this way TGID are always in /proc and TID in /proc/TGID/task. -- Guillaume - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Re : Oops preceded by WARNING: at net/ipv4/tcp_input.c:1571 tcp_remove_reno_sacks()
David Miller <[EMAIL PROTECTED]> wrote: > Chazarain please let us know if it does indeed cure your > problem. Unfortunately, I couldn't manage to reproduce the problem with an unpatched kernel. But your investigation Ilpo was really impressive. BTW, even though I messed up the yahoo webmail configuration, you can call me by my first name: Guillaume ;-) Thanks again for such an awesome bug fixing attitude! -- Guillaume - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: PROBLEM: oops, Linus tree: 2.6.23-g4fa4d23f, BUG: unable to handle kernel NULL pointer dereference at virtual address 00000004
Le Sun, 21 Oct 2007 13:16:32 +0800, Coly Li <[EMAIL PROTECTED]> a écrit : > > This should be fixed in recent git by > > http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=9b013e05e0289c190a53d78ca029e2f21c0e4485 > > > Maybe we encounter same condition, at least the symbol name is same -- > sock_setsockopt. > [ 4327.550291] EFLAGS: 00010282 (2.6.23-bigsmp-g4fa4d23f #6) You are testing a kernel that does not contain the aforementioned fix, so you should update your git checkout (using a kernel that can connect to the Internet ;-) ) and test the new kernel. Thanks. -- Guillaume - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: PROBLEM: oops, Linus tree: 2.6.23-g4fa4d23f, BUG: unable to handle kernel NULL pointer dereference at virtual address 00000004
> > BUG: unable to handle kernel NULL pointer dereference at virtual address > > 0004 This should be fixed in recent git by http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=9b013e05e0289c190a53d78ca029e2f21c0e4485 HTH. -- Guillaume - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: kernel BUG at net/core/dev.c:1383 skb_checksum_help: BUG_ON(offset > (int)skb->len)
Le Mon, 15 Oct 2007 13:15:05 +0300 (EEST), "Ilpo Järvinen" <[EMAIL PROTECTED]> a écrit : > ...Never mind, noticed the fix later on. Yes, but here is it anyway, in case you see something fishy. (gdb) p *(struct tcp_sock *)skb->sk $4 = {inet_conn = {icsk_inet = {sk = {__sk_common = {skc_family = 2, skc_state = 1 '\001', skc_reuse = 1 '\001', skc_bound_dev_if = 0, skc_node = {next = 0x0, pprev = 0xc6179450}, skc_bind_node = { next = 0xf5227550, pprev = 0xeebd3110}, skc_refcnt = { counter = 4}, skc_hash = 710603402, skc_prot = 0xc03f8720, skc_net = 0xc048ad60}, sk_shutdown = 0 '\0', sk_no_check = 0 '\0', sk_userlocks = 0 '\0', sk_protocol = 6 '\006', sk_type = 1, sk_rcvbuf = 87380, sk_lock = {slock = {raw_lock = {}}, owned = 0, wq = {lock = {raw_lock = {}}, task_list = {next = 0xf5180474, prev = 0xf5180474}}}, sk_backlog = {head = 0x0, tail = 0x0}, sk_sleep = 0xf5770918, sk_dst_cache = 0xed3db300, sk_policy = {0x0, 0x0}, sk_dst_lock = { raw_lock = {}}, sk_rmem_alloc = {counter = 63680}, sk_wmem_alloc = {counter = 488}, sk_omem_alloc = {counter = 0}, sk_sndbuf = 76188, sk_receive_queue = {next = 0xf51804a4, prev = 0xf51804a4, qlen = 0, lock = { raw_lock = {}}}, sk_write_queue = { next = 0xe218dc00, prev = 0xf0fdba80, qlen = 25, lock = { raw_lock = {}}}, sk_async_wait_queue = { next = 0x0, prev = 0x0, qlen = 0, lock = { raw_lock = {}}}, sk_wmem_queued = 33896, sk_forward_alloc = 4824, sk_allocation = 208, sk_route_caps = 0, sk_gso_type = 1, sk_rcvlowat = 1, sk_flags = 17152, sk_lingertime = 0, sk_error_queue = {next = 0xf51804e8, prev = 0xf51804e8, qlen = 0, lock = {raw_lock = {}}}, sk_prot_creator = 0xc03f8720, sk_callback_lock = { raw_lock = {}}, sk_err = 0, sk_err_soft = 0, sk_ack_backlog = 0, sk_max_ack_backlog = 50, sk_priority = 2, sk_peercred = {pid = 0, uid = 4294967295, gid = 4294967295}, sk_rcvtimeo = 2147483647, sk_sndtimeo = 2147483647, sk_filter = 0x0, sk_protinfo = 0x0, sk_timer = {entry = {next = 0x0, prev = 0xc04768e8}, expires = 2104092, function = 0xc02fa3b8 , data = 4111991872, base = 0xc0476800}, sk_stamp = {tv64 = 3294967295}, sk_socket = 0xf5770900, sk_user_data = 0x0, sk_sndmsg_page = 0x0, sk_send_head = 0xcc26cc00, sk_sndmsg_off = 0, sk_write_pending = 0, sk_security = 0x0, sk_state_change = 0xc02c2737 , sk_data_ready = 0xc02c2f8c , sk_write_space = 0xc02c6dc7 , sk_error_report = 0xc02c2f22 , sk_backlog_rcv = 0xc02fbc3a , sk_destruct = 0xc0308062 }, pinet6 = 0x0, daddr = 1743516497, rcv_saddr = 50374848, dport = 11768, num = 6881, saddr = 50374848, uc_ttl = -1, cmsg_flags = 0, opt = 0x0, sport = 57626, id = 19592, tos = 8 '\b', mc_ttl = 47 '/', pmtudisc = 1 '\001', recverr = 0 '\0', is_icsk = 1 '\001', freebind = 0 '\0', hdrincl = 0 '\0', mc_loop = 1 '\001', mc_index = 3, mc_addr = 0, mc_list = 0x0, cork = {flags = 0, fragsize = 0, opt = 0x0, rt = 0x0, length = 0, addr = 0, fl = {oif = 0, iif = 0, mark = 0, nl_u = { ip4_u = {daddr = 0, saddr = 0, tos = 0 '\0', scope = 0 '\0'}, ip6_u = {daddr = {in6_u = {u6_addr8 = {0 '\0' }, u6_addr16 = {0, 0, 0, 0, 0, 0, 0, 0}, u6_addr32 = {0, 0, 0, 0}}}, saddr = {in6_u = {u6_addr8 = { 0 '\0' }, u6_addr16 = {0, 0, 0, 0, 0, 0, 0, 0}, u6_addr32 = {0, 0, 0, 0}}}, flowlabel = 0}, dn_u = { daddr = 0, saddr = 0, scope = 0 '\0'}}, proto = 0 '\0', flags = 0 '\0', uli_u = {ports = {sport = 0, dport = 0}, icmpt = { type = 0 '\0', code = 0 '\0'}, dnports = {sport = 0, dport = 0}, spi = 0, mht = {type = 0 '\0'}}, secid = 0}}}, icsk_accept_queue = {rskq_accept_head = 0x0, rskq_accept_tail = 0x0, syn_wait_lock = {raw_lock = {}}, rskq_defer_accept = 0 '\0', listen_opt = 0x0}, icsk_bind_hash = 0xc639e820, icsk_timeout = 4955116, icsk_retransmit_timer = {entry = {next = 0xc04770e0, prev = 0xc03e3e50}, expires = 4955116, function = 0xc02fa6fc , data = 4111991872, base = 0xc0476800}, icsk_delack_timer = {entry = { next = 0x0, prev = 0x200200}, expires = 4944512, function = 0xc02fa57a , data = 4111991872, base = 0xc0476800}, icsk_rto = 5009, icsk_pmtu_cookie = 1500, icsk_ca_ops = 0xc03fa3e0, icsk_af_ops = 0xc03f86e0, icsk_sync_mss = 0xc02f6efd , icsk_ca_state = 3 '\003', icsk_retransmits = 0 '\0', icsk_pending = 1 '\001', icsk_backoff = 0 '\0', icsk_syn_retries = 0 '\0', icsk_probes_out = 0 '\0', icsk_ext_hdr_len = 0, icsk_ack = {pending = 0 '\0', quick = 0 '\0', pingpong
Re: [NET]: Fix csum_start update in pskb_expand_head
Le Mon, 15 Oct 2007 12:57:23 +0800, Herbert Xu <[EMAIL PROTECTED]> a écrit : > [NET]: Fix csum_start update in pskb_expand_head > [NET]: Avoid copying TCP packets unnecessarily I am Bittorrenting for a few hours with these patches, and they seem to work well. Thanks for the quick response. > ethtool -k eth1 is an ipw2200 [root ~]# ethtool -k eth1 Offload parameters for eth1: Cannot get device rx csum settings: Operation not supported rx-checksumming: off tx-checksumming: off scatter-gather: off tcp segmentation offload: off udp fragmentation offload: off generic segmentation offload: off Just in case you get a new interest ;-) Thanks. -- Guillaume - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: kernel BUG at net/core/dev.c:1383 skb_checksum_help: BUG_ON(offset > (int)skb->len)
Le Sun, 14 Oct 2007 19:26:40 +0200, Guillaume Chazarain <[EMAIL PROTECTED]> a écrit : > #0 0xc02c9d5e in skb_checksum_help (skb=0xe218dcb0) at net/core/dev.c:1372 > 1372BUG_ON(offset > (int)skb->len); Just another data point, it seems that running the standard Bittorrent client helps triggering the bug. Thanks. -- Guillaume - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Patch "[PKT_SCHED]: PSCHED_TADD() and PSCHED_TADD2() can result,tv_usec >= 1000000" seems wrong
Shuya MAEDA wrote : "while (__delta > USEC_PER_SEC){ ... }", but I think it should be "while (__delta >= USEC_PER_SEC){ ... }". Is it right? I agree, good catch :-) Thanks. -- Guillaume In PSCHED_TADD and PSCHED_TADD2, if delta is less than tv.tv_usec (so, less than USEC_PER_SEC too) then tv_res will be smaller than tv. The affectation "(tv_res).tv_usec = __delta;" is wrong. The fix is to revert to the original code before 4ee303dfeac6451b402e3d8512723d3a0f861857 and change the 'if' in 'while'. [Shuya MAEDA: "while (__delta >= USEC_PER_SEC){ ... }" instead of "while (__delta > USEC_PER_SEC){ ... }"] Signed-off-by: Guillaume Chazarain <[EMAIL PROTECTED]> --- pkt_sched.h | 18 ++ 1 file changed, 6 insertions(+), 12 deletions(-) --- a/include/net/pkt_sched.h +++ b/include/net/pkt_sched.h @@ -169,23 +169,17 @@ psched_tod_diff(int delta_sec, int bound #define PSCHED_TADD2(tv, delta, tv_res) \ ({ \ - int __delta = (delta); \ - (tv_res) = (tv); \ - while(__delta >= USEC_PER_SEC){ \ - (tv_res).tv_sec++; \ - __delta -= USEC_PER_SEC; \ - } \ + int __delta = (tv).tv_usec + (delta); \ + (tv_res).tv_sec = (tv).tv_sec; \ + while (__delta >= USEC_PER_SEC) { (tv_res).tv_sec++; __delta -= USEC_PER_SEC; } \ (tv_res).tv_usec = __delta; \ }) #define PSCHED_TADD(tv, delta) \ ({ \ - int __delta = (delta); \ - while(__delta >= USEC_PER_SEC){ \ - (tv).tv_sec++; \ - __delta -= USEC_PER_SEC; \ - } \ - (tv).tv_usec = __delta; \ + (tv).tv_usec += (delta); \ + while ((tv).tv_usec >= USEC_PER_SEC) { (tv).tv_sec++; \ + (tv).tv_usec -= USEC_PER_SEC; } \ }) /* Set/check that time is in the "past perfect";
Re: [PATCH] clear skb cb on IP input
Herbert Xu wrote : Probably. Patches are welcome :) Here are they, in both case I checked that the stuff to clear was not already cleared, but I could not produce any misbehavior by writing random junk instead of clearing the data. All my tests were on the loopback using UML. For IPv4, the added safety seems worth, but for IPv6 it's less clear. Thanks. -- Guillaume Clear the accumulated junk in IP6CB when starting to handle an IPV6 packet. Signed-off-by: Guillaume Chazarain <[EMAIL PROTECTED]> --- ip6_input.c |2 ++ 1 file changed, 2 insertions(+) --- a/net/ipv6/ip6_input.c +++ b/net/ipv6/ip6_input.c @@ -70,6 +70,8 @@ int ipv6_rcv(struct sk_buff *skb, struct IP6_INC_STATS_BH(IPSTATS_MIB_INDISCARDS); goto out; } + + memset(IP6CB(skb), 0, sizeof(struct inet6_skb_parm)); /* * Store incoming device index. When the packet will Clear the whole IPCB, this clears also IPCB(skb)->flags. Signed-off-by: Guillaume Chazarain <[EMAIL PROTECTED]> --- ip_input.c |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c @@ -429,7 +429,7 @@ int ip_rcv(struct sk_buff *skb, struct n } /* Remove any debris in the socket control block */ - memset(&(IPCB(skb)->opt), 0, sizeof(struct ip_options)); + memset(IPCB(skb), 0, sizeof(struct inet_skb_parm)); return NF_HOOK(PF_INET, NF_IP_PRE_ROUTING, skb, dev, NULL, ip_rcv_finish);
Re: [PATCH] clear skb cb on IP input
chas williams - CONTRACTOR wrote: why does the input side of the ip layer believe the cb contains valid data? it should zero the contents of the cb, or just fill in the cb correctly when the packet arrives at its doorstop. Why not clearing the whole IPCB(skb) instead of just IPCB(skb)->opts? that would also clear IPCB(skb)->flags. And, does not ipv6 need the same treatment with IP6CB? Regards. -- Guillaume - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] Fix slab corruption with netem (2nd try)
CONFIG_DEBUG_SLAB found the following bug: netem_enqueue() in sch_netem.c gets a pointer inside a slab object: struct netem_skb_cb *cb = (struct netem_skb_cb *)skb->cb; But then, the slab object may be freed: skb = skb_unshare(skb, GFP_ATOMIC) cb is still pointing inside the freed skb, so here is a patch to initialize cb later, and make it clear that initializing it sooner is a bad idea. [From Stephen Hemminger: leave cb unitialized in order to let gcc complain in case of use before initialization] Thanks. -- Guillaume Signed-off-by: Guillaume Chazarain <[EMAIL PROTECTED]> --- net/sched/sch_netem.c |5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff -r 1b8d63e34819 net/sched/sch_netem.c --- a/net/sched/sch_netem.c +++ b/net/sched/sch_netem.c @@ -148,7 +148,8 @@ static int netem_enqueue(struct sk_buff static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) { struct netem_sched_data *q = qdisc_priv(sch); - struct netem_skb_cb *cb = (struct netem_skb_cb *)skb->cb; + /* We don't fill cb now as skb_unshare() may invalidate it */ + struct netem_skb_cb *cb; struct sk_buff *skb2; int ret; int count = 1; @@ -200,6 +201,7 @@ static int netem_enqueue(struct sk_buff skb->data[net_random() % skb_headlen(skb)] ^= 1<<(net_random() % 8); } + cb = (struct netem_skb_cb *)skb->cb; if (q->gap == 0 /* not doing reordering */ || q->counter < q->gap /* inside last reordering gap */ || q->reorder < get_crandom(&q->reorder_cor)) {
Re: [PATCH] Fix slab corruption with netem
Stephen Hemminger wrote : -struct netem_skb_cb *cb = (struct netem_skb_cb *)skb->cb; +/* We don't fill cb now as skb_unshare() may invalidate it */ +struct netem_skb_cb *cb = NULL; Would rather leave it unitialized, rather than setting to NULL. I find that strange. If someone mistakenly uses cb before it is initialized it could be hard to figure out why some memory is corrupted. But by initializing cb to NULL, it will always trigger an Oops, so it will be easier to debug in this case. Cheers. -- Guillaume - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] Fix slab corruption with netem
Hello, CONFIG_DEBUG_SLAB found the following bug: netem_enqueue() in sch_netem.c gets a pointer inside a slab object: struct netem_skb_cb *cb = (struct netem_skb_cb *)skb->cb; But then, the slab object may be freed: skb = skb_unshare(skb, GFP_ATOMIC) cb is still pointing inside the freed skb, so here is a patch to initialize cb later, and make it clear that initializing it sooner is a bad idea. Thanks. -- Guillaume --- a/net/sched/sch_netem.c +++ b/net/sched/sch_netem.c @@ -148,7 +148,8 @@ static int netem_enqueue(struct sk_buff static int netem_enqueue(struct sk_buff *skb, struct Qdisc *sch) { struct netem_sched_data *q = qdisc_priv(sch); - struct netem_skb_cb *cb = (struct netem_skb_cb *)skb->cb; + /* We don't fill cb now as skb_unshare() may invalidate it */ + struct netem_skb_cb *cb = NULL; struct sk_buff *skb2; int ret; int count = 1; @@ -200,6 +201,7 @@ static int netem_enqueue(struct sk_buff skb->data[net_random() % skb_headlen(skb)] ^= 1<<(net_random() % 8); } + cb = (struct netem_skb_cb *)skb->cb; if (q->gap == 0 /* not doing reordering */ || q->counter < q->gap /* inside last reordering gap */ || q->reorder < get_crandom(&q->reorder_cor)) { -- Signed-off-by: Guillaume Chazarain <[EMAIL PROTECTED]>
Re: Netem does not work with loopback
Stephen Hemminger wrote: No, the correct fix is to make IP input not accept any options from the device. OK. Does this work? Yes it does. Thank you very much. -- Guillaume - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Netem does not work with loopback
Stephen Hemminger wrote : Isn't the skb owned by netem at that point... Thank you, that makes sense to me. But then the loopback device reinjects the skb without cleaning skb->cb. The attached patch solves the problem for me (netem on lo). Maybe the correct solution would be to make a skb->destructor function for netem, but I am not sure this is the intended use of a destructor function. Thanks. -- Guillaume --- a/drivers/net/loopback.c +++ b/drivers/net/loopback.c @@ -156,6 +156,9 @@ lb_stats->tx_packets = lb_stats->rx_packets; put_cpu(); + /* Get rid of all the private data accumulated in the sending part */ + memset(skb->cb, 0, sizeof(skb->cb)); + netif_rx(skb); return(0); -- Signed-off-by: Guillaume Chazarain <[EMAIL PROTECTED]>
Netem does not work with loopback
Hello, Is it a known problem that the Netem qdisc is very unreliable on the loopback (unlike on a true NIC)? This seems to come from its usage of skb->cb which conflicts with IPCB. For instance, the field IPCB(skb)->opt.optlen becomes non-null and memory corruption follows. I ``worked around'' this conflict with the following ugly hack: --- a/net/sched/sch_netem.c +++ b/net/sched/sch_netem.c @@ -79,6 +79,7 @@ struct netem_sched_data { /* Time stamp put into socket buffer control block */ struct netem_skb_cb { +char padding[32]; /* to avoid stepping over IPCB when used on the loopback */ psched_time_ttime_to_send; }; Hopefully someone has a better solution :-) Thanks. -- Guillaume - To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html
Patch "[PKT_SCHED]: PSCHED_TADD() and PSCHED_TADD2() can result,tv_usec >= 1000000" seems wrong
Hello, This patch: http://www.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commitdiff;h=4ee303dfeac6451b402e3d8512723d3a0f861857 looks wrong. In PSCHED_TADD2, if delta is less than tv.tv_usec (so, less than USEC_PER_SEC too) then tv_res will be before tv. The affectation (tv_res).tv_usec = __delta; is wrong. The same applies to PSCHED_TADD. I think the correct fix is simply to restore the original code and change the 'if' in a 'while'. So here are two patches for the two possible solutions : o Reverting the commit and applying from_before_patch_to_correct.diff o Applying from_tip_to_correct.diff Thanks. -- Guillaume --- a/include/net/pkt_sched.h.before 2006-07-14 15:58:53.0 +0200 +++ b/include/net/pkt_sched.h 2006-07-14 15:59:10.0 +0200 @@ -171,14 +171,14 @@ ({ \ int __delta = (tv).tv_usec + (delta); \ (tv_res).tv_sec = (tv).tv_sec; \ - if (__delta > USEC_PER_SEC) { (tv_res).tv_sec++; __delta -= USEC_PER_SEC; } \ + while (__delta > USEC_PER_SEC) { (tv_res).tv_sec++; __delta -= USEC_PER_SEC; } \ (tv_res).tv_usec = __delta; \ }) #define PSCHED_TADD(tv, delta) \ ({ \ (tv).tv_usec += (delta); \ - if ((tv).tv_usec > USEC_PER_SEC) { (tv).tv_sec++; \ + while ((tv).tv_usec > USEC_PER_SEC) { (tv).tv_sec++; \ (tv).tv_usec -= USEC_PER_SEC; } \ }) -- Signed-off-by: Guillaume Chazarain <[EMAIL PROTECTED]> diff -r 672dc37bf355 include/net/pkt_sched.h --- a/include/net/pkt_sched.h Fri Jul 14 06:57:04 2006 +0700 +++ b/include/net/pkt_sched.h Fri Jul 14 15:58:04 2006 +0200 @@ -169,23 +169,17 @@ psched_tod_diff(int delta_sec, int bound #define PSCHED_TADD2(tv, delta, tv_res) \ ({ \ - int __delta = (delta); \ - (tv_res) = (tv); \ - while(__delta >= USEC_PER_SEC){ \ - (tv_res).tv_sec++; \ - __delta -= USEC_PER_SEC; \ - } \ + int __delta = (tv).tv_usec + (delta); \ + (tv_res).tv_sec = (tv).tv_sec; \ + while (__delta > USEC_PER_SEC) { (tv_res).tv_sec++; __delta -= USEC_PER_SEC; } \ (tv_res).tv_usec = __delta; \ }) #define PSCHED_TADD(tv, delta) \ ({ \ - int __delta = (delta); \ - while(__delta >= USEC_PER_SEC){ \ - (tv).tv_sec++; \ - __delta -= USEC_PER_SEC; \ - } \ - (tv).tv_usec = __delta; \ + (tv).tv_usec += (delta); \ + while ((tv).tv_usec > USEC_PER_SEC) { (tv).tv_sec++; \ + (tv).tv_usec -= USEC_PER_SEC; } \ }) /* Set/check that time is in the "past perfect"; -- Signed-off-by: Guillaume Chazarain <[EMAIL PROTECTED]>