Em Mon, Dec 03, 2007 at 08:35:12AM +0000, Gerrit Renker escreveu: > Hi Arnaldo, > > hank you for going through this. I have just backported your recent patches > of 2.6.25 > to the DCCP/CCID4/Faster Restart test tree at > git://eden-feed.erg.abdn.ac.uk/dccp_exp {dccp,ccid4,dccp_fr} > as per subsequent message. > | do, so please consider moving DCCP discussion to [EMAIL PROTECTED], > | where lots of smart networking folks are present and can help our > efforts > | on turning RFCs to code. > Are you suggesting using netdev exclusively or in addition to [EMAIL > PROTECTED]
Well, since at least one person that has contributed significantly in the past has said he can't cope with traffic on netdev, we can CC [EMAIL PROTECTED] > > | Please take a look at this patch series where I reorganized your work > on the new > | TFRC rx history handling code. I'll wait for your considerations and then > do as many > | interactions as reasonable to get your work merged. > | > | It should be completely equivalent, plus some fixes and optimizations, > such as: > It will be necessary to address these points one-by-one. Before diving into > making > fixes and `optimisations', have you tested your code? The patches you are > referring to I have performed basic tests, and when doing so noticed a bug in inet_diag, that I commented with Herbert Xu and he has since provided a fix. > have been posted and re-posted for a period of over 9 months on [EMAIL > PROTECTED], and Being posted and re-posted does not guarantee that the patch is OK or that is in a form that is acceptable to all tree maintainers. DaveM is subscribed to [EMAIL PROTECTED] and could have picked this if he had the time to do the review. I didn't, but now I'm trying to spend my time on reviewing your patches and in the process doing modifications I find appropriate while trying hard not to introduce bugs in your hard work to get it merged. > there are regression tests which show that this code improves on the existing > Linux > implementation. These are labelled as `test tree' on > http://www.linux-foundation.org/en/Net:DCCP_Testing#Regression_testing > So if you are making changes to the code, I would like to ask if you have run > similar > regression tests, to avoid having to step back later. Fair enough, I will do that before asking Herbert or Dave to pull from my tree. > | . The code that allocates the RX ring deals with failures when one of the > entries in > | the ring buffer is not successfully allocated, the original code was > leaking the > | successfully allocated entries. Sorry for not point out exactly this, here it goes: Your original patch: +int tfrc_rx_hist_init(struct tfrc_rx_hist *h) +{ + int i; + + for (i = 0; i <= NDUPACK; i++) { + h->ring[i] = kmem_cache_alloc(tfrc_rxh_cache, GFP_ATOMIC); + if (h->ring[i] == NULL) + return 1; + } + h->loss_count = 0; + h->loss_start = 0; + return 0; +} +EXPORT_SYMBOL_GPL(tfrc_rx_hist_init); Then, in ccid3_hc_rx_init you do: static int ccid3_hc_rx_init(struct ccid *ccid, struct sock *sk) { struct ccid3_hc_rx_sock *hcrx = ccid_priv(ccid); ccid3_pr_debug("entry\n"); hcrx->ccid3hcrx_state = TFRC_RSTATE_NO_DATA; tfrc_lh_init(&hcrx->ccid3hcrx_li_hist); return tfrc_rx_hist_init(&hcrx->ccid3hcrx_hist); } So if tfrc_rx_hist_init fail to allocate, say, the last entry in the ring, it will return 1, and from looking at how you initialize h->loss_{count,start} to zero I assumed that the whole tfrc_rx_hist is not zeroed when tfrc_rx_hist_init is called, so one can also assume that the ring entries are not initialized to NULL and that if the error recovery is to assume that later on tfrc_rx_hist_cleanup is called we would not have a leak, but an OOPS when tfrc_rx_hist_cleanup tries to call kfree_cache_free on the uninitialized ring entries. But if you look at ccid_new(), that calls ccid3_hc_rx_init(), you'll see that when the ccid rx or hx routine fails, it just frees the struct ccid with the area where h->ring is, so, what was not cleaned up by the ccid init routine is effectively forgot, leaked. I first did the cleanup at tfrc_rx_hist_init (that I renamed to tfrc_rx_hist_alloc, since it doesn't just initializes things, but allocates entries from slab), but then I just made the rx history slab have arrays of tfrc_rx_hist_entry objects, not individual ones as your code always allocates them as arrays. > | . We do just one allocation for the ring buffer, as the number of entries > is fixed we > | should just do one allocation and not TFRC_NDUPACK times. > Will look at the first point in the patch; with regard to the second point I > agree, this > will make the code simpler, which is good. good > | . I haven't checked if all the code was commited, as I tried to introduce > just what was > | immediatelly used, probably we'll need to do some changes when working on > the merge > | of your loss intervals code. > Sorry I don't understand this point. Let me check now and tell you for sure: tfrc_rx_hist_delta_seqno and tfrc_rx_hist_swap were not included, as they were not used, we should introduce them later, when getting to the working on the loss interval code. > | . I changed the ccid3_hc_rx_packet_recv code to set hcrx->ccid3hcrx_s for > the first > | non-data packet instead of calling ccid3_hc_rx_set_state, that would use > 0 as the > | initial value in the EWMA calculation. > This is a misunderstanding. Non-data packets are not considered in the moving > average > for the data packet size `s'; and it would be an error to do (consider 40byte > Acks vs. > 1460byte data packets, also it is in RFC 4342). > Where would the zero initial value come from? I think this is also a > misunderstanding. > Please have a look below: > static void ccid3_hc_rx_packet_recv(struct sock *sk, struct sk_buff > *skb) > { > // ... > u32 sample, payload_size = skb->len - dccp_hdr(skb)->dccph_doff > * 4; > > if (unlikely(hcrx->ccid3hcrx_state == TFRC_RSTATE_NO_DATA)) { > if (is_data_packet) { > do_feedback = FBACK_INITIAL; > ccid3_hc_rx_set_state(sk, TFRC_RSTATE_DATA); > ccid3_hc_rx_update_s(hcrx, payload_size); > } > goto update_records; > } > > ==> Non-data packets are ignored for the purposes of computing s (this is in > the RFC), > consequently update_s() is only called for data packets; using the two > following > functions: > > > static inline u32 tfrc_ewma(const u32 avg, const u32 newval, const u8 > weight) > { > return avg ? (weight * avg + (10 - weight) * newval) / 10 : > newval; > } I hadn't considered that tfrc_ewma would for every packet check if the avg was 0 and I find it suboptimal now that I look at it, we are just feeding data packets, no? So checking just when we are at TFRC_RSTATE_NO_DATA, as your code does seems to be better, but not by calling ccid3_hc_rx_update_s, but just doing: <SNIP> { do_feedback = CCID3_FBACK_INITIAL; ccid3_hc_rx_set_state(sk, TFRC_RSTATE_DATA); hcrx->ccid3hcrx_s = payload_size; } <SNIP> > static inline void ccid3_hc_rx_update_s(struct ccid3_hc_rx_sock *hcrx, > int len) > { > if (likely(len > 0)) /* don't update on empty packets (e.g. > ACKs) */ > hcrx->ccid3hcrx_s = tfrc_ewma(hcrx->ccid3hcrx_s, len, > 9); > } And we also just do test for len > 0 in update_s, that looks like also excessive, no? As we should pass just data packets, perhaps we should just do a BUG_ON there. > > ==> Hence I can't see where a zero value should come from: ccid3hrx_s is > initially > initialised with zero (memset(...,0,...)); when first called, update_s() > will > feed a non-zero payload size to tfrc_ewma(), which will return `newval' > = payload_size, > hence the first data packet will contribute a non-zero payload_size. > Zero-sized DCCP-Data packets are pathological and are ignored by the CCID > calculations > (not by the receiver); a corresponding counterpart for zero-sized Understood, consider this one then an optimization and not a bugfix. My motivation to add this as an optimization had I realized that tfrc_ewma checks for avg being zero would have been greatly diminished, but since we are having all this discussion, I think the optimization is OK to have merged. > | > | It is available at: > | > | master.kernel.org:/pub/scm/linux/kernel/git/acme/net-2.6.25 > | > Need to do this separately. As said, the code has been developed and tested > over a long time, > it took a long while until it acted predictably, so being careful is very > important. Gerrit, I do these kinds of code reorganizations on the core Linux networking for ages, I'm not perfect (huh! :-P) but I also didn't performed extensive testing doing coverage analisys of all the imaginable possibilities, just did my best to improve the abstractions and the code, ocasionally fixing bugs as I went thru the existing code. So while I understand your concerns about being careful, rest asured I _am_ careful and will be even _more_ careful by using the regression tests you mentioned, as it would be a shame not to use them. But I can't just take your patches as-is all the time, I have my personal preferences and will try to use them when taking the time to merge code from anyone. > I would rather not have my patches merged and continue to run a test tree if > the current > changes alter the behaviour to the worse. Its not like that, you released your code as GPL, its out there, it would be a shame not to merge it, but not as-is all the time. I'm making sure I stick my name when I do major code changes while giving you due credit for your work. And heck, this was an [RFC], I didn't pushed this upstream before listening to your concerns. Its only fair that if you expect me to review your work, I should expect for you to review my work, even more when is to improve yours. Best Regards, - Arnaldo - To unsubscribe from this list: send the line "unsubscribe dccp" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html