This patch prepares adding TX history locking by changing all
functions which return a reference to a TX history object:
1) removal of dccp_tx_hist_head - nowhere used in the code;
2) change dccp_tx_hist_find_entry - the sole use is to look up a
timestamp for an Ack-ed packet; and then do garbage-collection.
The latter function is changed to return the desired timestamp instead of
a history object reference.
Not returning object references is necessary, since otherwise lists could
not be garbage-collected (or would have to use atomic reference counts).
Furthermore, the garbage-collection is now integrated into (2), since it
requires first a read access and then a write access at the same place in
the list: giving up the lock here would permit race condition.
Signed-off-by: Gerrit Renker <[EMAIL PROTECTED]>
Signed-off-by: Arnaldo Carvalho de Melo <[EMAIL PROTECTED]>
---
net/dccp/ccids/ccid3.c | 18 +++++++-----------
net/dccp/ccids/lib/packet_history.c | 27 +++++++++++++++++++++------
net/dccp/ccids/lib/packet_history.h | 16 ++--------------
3 files changed, 30 insertions(+), 31 deletions(-)
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index 131001b..0029979 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -421,10 +421,9 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk,
struct sk_buff *skb)
{
struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
struct ccid3_options_received *opt_recv;
- struct dccp_tx_hist_entry *packet;
- struct timeval now;
+ struct timeval now, t_send;
unsigned long t_nfb;
- u32 pinv, r_sample;
+ u32 pinv, r_sample, rc;
BUG_ON(hctx == NULL);
@@ -440,10 +439,10 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk,
struct sk_buff *skb)
default: return;
}
- /* get packet from history to look up t_recvdata */
- packet = dccp_tx_hist_find_entry(&hctx->ccid3hctx_hist,
- DCCP_SKB_CB(skb)->dccpd_ack_seq);
- if (unlikely(packet == NULL)) {
+ /* look up t_recvdata in packet history */
+ rc = dccp_tx_hist_get_send_time(ccid3_tx_hist, &hctx->ccid3hctx_hist,
+ DCCP_SKB_CB(skb)->dccpd_ack_seq,
&t_send);
+ if (unlikely(!rc)) {
DCCP_WARN("%s(%p), seqno %llu(%s) doesn't exist in history!\n",
dccp_role(sk), sk,
(unsigned long long)DCCP_SKB_CB(skb)->dccpd_ack_seq,
@@ -466,7 +465,7 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct
sk_buff *skb)
* R_sample = (t_now - t_recvdata) - t_elapsed
*/
skb_get_timestamp(skb, &now);
- r_sample = dccp_sample_rtt(sk, &now, &packet->dccphtx_tstamp);
+ r_sample = dccp_sample_rtt(sk, &now, &t_send);
/*
* Update RTT estimate (honours RTT from SYN exchange):
@@ -523,9 +522,6 @@ done_computing_x:
/* unschedule no feedback timer */
sk_stop_timer(sk, &hctx->ccid3hctx_no_feedback_timer);
- /* remove all packets older than the one acked from history */
- dccp_tx_hist_purge_older(ccid3_tx_hist,
- &hctx->ccid3hctx_hist, packet);
/*
* As we have calculated new ipi, delta, t_nom it is possible
* that we now can send a packet, so wake up dccp_wait_for_ccid
diff --git a/net/dccp/ccids/lib/packet_history.c
b/net/dccp/ccids/lib/packet_history.c
index 2e8ef42..d149b19 100644
--- a/net/dccp/ccids/lib/packet_history.c
+++ b/net/dccp/ccids/lib/packet_history.c
@@ -85,21 +85,36 @@ void dccp_tx_hist_delete(struct dccp_tx_hist *hist)
EXPORT_SYMBOL_GPL(dccp_tx_hist_delete);
-struct dccp_tx_hist_entry *
- dccp_tx_hist_find_entry(const struct list_head *list, const u64 seq)
+/**
+ * dccp_tx_hist_get_send_time - Retrieve timestamp of sent packet
+ *
+ * @hist: history slab associated with TX history
+ * @list: TX history list head
+ * @seq: 48-bit sequence number of packet in question
+ * @t_send: timestamp to be returned
+ * Returns 1 on success and then garbage-collects all older entries.
+ */
+int dccp_tx_hist_get_send_time(struct dccp_tx_hist *hist,
+ struct list_head *list, u64 seq,
+ struct timeval *t_send)
{
- struct dccp_tx_hist_entry *packet = NULL, *entry;
+ struct dccp_tx_hist_entry *entry;
+ int found = 0;
list_for_each_entry(entry, list, dccphtx_node)
if (entry->dccphtx_seqno == seq) {
- packet = entry;
+ found = 1;
+ *t_send = entry->dccphtx_tstamp;
break;
}
- return packet;
+ if (found)
+ dccp_tx_hist_purge_older(hist, list, entry);
+
+ return found;
}
-EXPORT_SYMBOL_GPL(dccp_tx_hist_find_entry);
+EXPORT_SYMBOL_GPL(dccp_tx_hist_get_send_time);
void dccp_tx_hist_purge(struct dccp_tx_hist *hist, struct list_head *list)
{
diff --git a/net/dccp/ccids/lib/packet_history.h
b/net/dccp/ccids/lib/packet_history.h
index 330b58f..da81709 100644
--- a/net/dccp/ccids/lib/packet_history.h
+++ b/net/dccp/ccids/lib/packet_history.h
@@ -80,20 +80,8 @@ static inline struct dccp_tx_hist_entry *
return entry;
}
-static inline struct dccp_tx_hist_entry *
- dccp_tx_hist_head(struct list_head *list)
-{
- struct dccp_tx_hist_entry *head = NULL;
-
- if (!list_empty(list))
- head = list_entry(list->next, struct dccp_tx_hist_entry,
- dccphtx_node);
- return head;
-}
-
-extern struct dccp_tx_hist_entry *
- dccp_tx_hist_find_entry(const struct list_head *list,
- const u64 seq);
+extern int dccp_tx_hist_get_send_time(struct dccp_tx_hist *, struct list_head
*,
+ u64 seq, struct timeval *t_send);
static inline void dccp_tx_hist_add_entry(struct list_head *list,
struct dccp_tx_hist_entry *entry)
--
1.5.0.6
-
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