aboutsummaryrefslogtreecommitdiffstats
path: root/net/dccp
diff options
context:
space:
mode:
Diffstat (limited to 'net/dccp')
-rw-r--r--net/dccp/ccids/ccid3.c18
-rw-r--r--net/dccp/ccids/lib/loss_interval.c92
-rw-r--r--net/dccp/ccids/lib/loss_interval.h12
3 files changed, 36 insertions, 86 deletions
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index 9d2e2c193cc6..407f10c742ae 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -49,7 +49,6 @@ static int ccid3_debug;
49 49
50static struct dccp_tx_hist *ccid3_tx_hist; 50static struct dccp_tx_hist *ccid3_tx_hist;
51static struct dccp_rx_hist *ccid3_rx_hist; 51static struct dccp_rx_hist *ccid3_rx_hist;
52static struct dccp_li_hist *ccid3_li_hist;
53 52
54/* 53/*
55 * Transmitter Half-Connection Routines 54 * Transmitter Half-Connection Routines
@@ -844,7 +843,7 @@ static int ccid3_hc_rx_detect_loss(struct sock *sk,
844 while (dccp_delta_seqno(hcrx->ccid3hcrx_seqno_nonloss, seqno) 843 while (dccp_delta_seqno(hcrx->ccid3hcrx_seqno_nonloss, seqno)
845 > TFRC_RECV_NUM_LATE_LOSS) { 844 > TFRC_RECV_NUM_LATE_LOSS) {
846 loss = 1; 845 loss = 1;
847 dccp_li_update_li(sk, ccid3_li_hist, 846 dccp_li_update_li(sk,
848 &hcrx->ccid3hcrx_li_hist, 847 &hcrx->ccid3hcrx_li_hist,
849 &hcrx->ccid3hcrx_hist, 848 &hcrx->ccid3hcrx_hist,
850 &hcrx->ccid3hcrx_tstamp_last_feedback, 849 &hcrx->ccid3hcrx_tstamp_last_feedback,
@@ -1011,7 +1010,7 @@ static void ccid3_hc_rx_exit(struct sock *sk)
1011 dccp_rx_hist_purge(ccid3_rx_hist, &hcrx->ccid3hcrx_hist); 1010 dccp_rx_hist_purge(ccid3_rx_hist, &hcrx->ccid3hcrx_hist);
1012 1011
1013 /* Empty loss interval history */ 1012 /* Empty loss interval history */
1014 dccp_li_hist_purge(ccid3_li_hist, &hcrx->ccid3hcrx_li_hist); 1013 dccp_li_hist_purge(&hcrx->ccid3hcrx_li_hist);
1015} 1014}
1016 1015
1017static void ccid3_hc_rx_get_info(struct sock *sk, struct tcp_info *info) 1016static void ccid3_hc_rx_get_info(struct sock *sk, struct tcp_info *info)
@@ -1095,19 +1094,12 @@ static __init int ccid3_module_init(void)
1095 if (ccid3_tx_hist == NULL) 1094 if (ccid3_tx_hist == NULL)
1096 goto out_free_rx; 1095 goto out_free_rx;
1097 1096
1098 ccid3_li_hist = dccp_li_hist_new("ccid3");
1099 if (ccid3_li_hist == NULL)
1100 goto out_free_tx;
1101
1102 rc = ccid_register(&ccid3); 1097 rc = ccid_register(&ccid3);
1103 if (rc != 0) 1098 if (rc != 0)
1104 goto out_free_loss_interval_history; 1099 goto out_free_tx;
1105out: 1100out:
1106 return rc; 1101 return rc;
1107 1102
1108out_free_loss_interval_history:
1109 dccp_li_hist_delete(ccid3_li_hist);
1110 ccid3_li_hist = NULL;
1111out_free_tx: 1103out_free_tx:
1112 dccp_tx_hist_delete(ccid3_tx_hist); 1104 dccp_tx_hist_delete(ccid3_tx_hist);
1113 ccid3_tx_hist = NULL; 1105 ccid3_tx_hist = NULL;
@@ -1130,10 +1122,6 @@ static __exit void ccid3_module_exit(void)
1130 dccp_rx_hist_delete(ccid3_rx_hist); 1122 dccp_rx_hist_delete(ccid3_rx_hist);
1131 ccid3_rx_hist = NULL; 1123 ccid3_rx_hist = NULL;
1132 } 1124 }
1133 if (ccid3_li_hist != NULL) {
1134 dccp_li_hist_delete(ccid3_li_hist);
1135 ccid3_li_hist = NULL;
1136 }
1137} 1125}
1138module_exit(ccid3_module_exit); 1126module_exit(ccid3_module_exit);
1139 1127
diff --git a/net/dccp/ccids/lib/loss_interval.c b/net/dccp/ccids/lib/loss_interval.c
index 28eac9be6634..e6b1f0c913ec 100644
--- a/net/dccp/ccids/lib/loss_interval.c
+++ b/net/dccp/ccids/lib/loss_interval.c
@@ -18,71 +18,26 @@
18#include "packet_history.h" 18#include "packet_history.h"
19#include "tfrc.h" 19#include "tfrc.h"
20 20
21struct dccp_li_hist *dccp_li_hist_new(const char *name) 21struct kmem_cache *dccp_li_cachep __read_mostly;
22{
23 struct dccp_li_hist *hist = kmalloc(sizeof(*hist), GFP_ATOMIC);
24 static const char dccp_li_hist_mask[] = "li_hist_%s";
25 char *slab_name;
26
27 if (hist == NULL)
28 goto out;
29
30 slab_name = kmalloc(strlen(name) + sizeof(dccp_li_hist_mask) - 1,
31 GFP_ATOMIC);
32 if (slab_name == NULL)
33 goto out_free_hist;
34
35 sprintf(slab_name, dccp_li_hist_mask, name);
36 hist->dccplih_slab = kmem_cache_create(slab_name,
37 sizeof(struct dccp_li_hist_entry),
38 0, SLAB_HWCACHE_ALIGN,
39 NULL, NULL);
40 if (hist->dccplih_slab == NULL)
41 goto out_free_slab_name;
42out:
43 return hist;
44out_free_slab_name:
45 kfree(slab_name);
46out_free_hist:
47 kfree(hist);
48 hist = NULL;
49 goto out;
50}
51
52EXPORT_SYMBOL_GPL(dccp_li_hist_new);
53
54void dccp_li_hist_delete(struct dccp_li_hist *hist)
55{
56 const char* name = kmem_cache_name(hist->dccplih_slab);
57
58 kmem_cache_destroy(hist->dccplih_slab);
59 kfree(name);
60 kfree(hist);
61}
62
63EXPORT_SYMBOL_GPL(dccp_li_hist_delete);
64 22
65static inline struct dccp_li_hist_entry * 23static inline struct dccp_li_hist_entry *dccp_li_hist_entry_new(const gfp_t prio)
66 dccp_li_hist_entry_new(struct dccp_li_hist *hist,
67 const gfp_t prio)
68{ 24{
69 return kmem_cache_alloc(hist->dccplih_slab, prio); 25 return kmem_cache_alloc(dccp_li_cachep, prio);
70} 26}
71 27
72static inline void dccp_li_hist_entry_delete(struct dccp_li_hist *hist, 28static inline void dccp_li_hist_entry_delete(struct dccp_li_hist_entry *entry)
73 struct dccp_li_hist_entry *entry)
74{ 29{
75 if (entry != NULL) 30 if (entry != NULL)
76 kmem_cache_free(hist->dccplih_slab, entry); 31 kmem_cache_free(dccp_li_cachep, entry);
77} 32}
78 33
79void dccp_li_hist_purge(struct dccp_li_hist *hist, struct list_head *list) 34void dccp_li_hist_purge(struct list_head *list)
80{ 35{
81 struct dccp_li_hist_entry *entry, *next; 36 struct dccp_li_hist_entry *entry, *next;
82 37
83 list_for_each_entry_safe(entry, next, list, dccplih_node) { 38 list_for_each_entry_safe(entry, next, list, dccplih_node) {
84 list_del_init(&entry->dccplih_node); 39 list_del_init(&entry->dccplih_node);
85 kmem_cache_free(hist->dccplih_slab, entry); 40 kmem_cache_free(dccp_li_cachep, entry);
86 } 41 }
87} 42}
88 43
@@ -134,17 +89,16 @@ u32 dccp_li_hist_calc_i_mean(struct list_head *list)
134 89
135EXPORT_SYMBOL_GPL(dccp_li_hist_calc_i_mean); 90EXPORT_SYMBOL_GPL(dccp_li_hist_calc_i_mean);
136 91
137static int dccp_li_hist_interval_new(struct dccp_li_hist *hist, 92static int dccp_li_hist_interval_new(struct list_head *list,
138 struct list_head *list,
139 const u64 seq_loss, const u8 win_loss) 93 const u64 seq_loss, const u8 win_loss)
140{ 94{
141 struct dccp_li_hist_entry *entry; 95 struct dccp_li_hist_entry *entry;
142 int i; 96 int i;
143 97
144 for (i = 0; i < DCCP_LI_HIST_IVAL_F_LENGTH; i++) { 98 for (i = 0; i < DCCP_LI_HIST_IVAL_F_LENGTH; i++) {
145 entry = dccp_li_hist_entry_new(hist, GFP_ATOMIC); 99 entry = dccp_li_hist_entry_new(GFP_ATOMIC);
146 if (entry == NULL) { 100 if (entry == NULL) {
147 dccp_li_hist_purge(hist, list); 101 dccp_li_hist_purge(list);
148 DCCP_BUG("loss interval list entry is NULL"); 102 DCCP_BUG("loss interval list entry is NULL");
149 return 0; 103 return 0;
150 } 104 }
@@ -260,7 +214,7 @@ found:
260 return 1000000 / p; 214 return 1000000 / p;
261} 215}
262 216
263void dccp_li_update_li(struct sock *sk, struct dccp_li_hist *li_hist, 217void dccp_li_update_li(struct sock *sk,
264 struct list_head *li_hist_list, 218 struct list_head *li_hist_list,
265 struct list_head *hist_list, 219 struct list_head *hist_list,
266 struct timeval *last_feedback, u16 s, u32 bytes_recv, 220 struct timeval *last_feedback, u16 s, u32 bytes_recv,
@@ -270,8 +224,8 @@ void dccp_li_update_li(struct sock *sk, struct dccp_li_hist *li_hist,
270 u64 seq_temp; 224 u64 seq_temp;
271 225
272 if (list_empty(li_hist_list)) { 226 if (list_empty(li_hist_list)) {
273 if (!dccp_li_hist_interval_new(li_hist, li_hist_list, 227 if (!dccp_li_hist_interval_new(li_hist_list, seq_loss,
274 seq_loss, win_loss)) 228 win_loss))
275 return; 229 return;
276 230
277 head = list_entry(li_hist_list->next, struct dccp_li_hist_entry, 231 head = list_entry(li_hist_list->next, struct dccp_li_hist_entry,
@@ -293,7 +247,7 @@ void dccp_li_update_li(struct sock *sk, struct dccp_li_hist *li_hist,
293 /* new loss event detected */ 247 /* new loss event detected */
294 /* calculate last interval length */ 248 /* calculate last interval length */
295 seq_temp = dccp_delta_seqno(head->dccplih_seqno, seq_loss); 249 seq_temp = dccp_delta_seqno(head->dccplih_seqno, seq_loss);
296 entry = dccp_li_hist_entry_new(li_hist, GFP_ATOMIC); 250 entry = dccp_li_hist_entry_new(GFP_ATOMIC);
297 251
298 if (entry == NULL) { 252 if (entry == NULL) {
299 DCCP_BUG("out of memory - can not allocate entry"); 253 DCCP_BUG("out of memory - can not allocate entry");
@@ -304,7 +258,7 @@ void dccp_li_update_li(struct sock *sk, struct dccp_li_hist *li_hist,
304 258
305 tail = li_hist_list->prev; 259 tail = li_hist_list->prev;
306 list_del(tail); 260 list_del(tail);
307 kmem_cache_free(li_hist->dccplih_slab, tail); 261 kmem_cache_free(dccp_li_cachep, tail);
308 262
309 /* Create the newest interval */ 263 /* Create the newest interval */
310 entry->dccplih_seqno = seq_loss; 264 entry->dccplih_seqno = seq_loss;
@@ -314,3 +268,19 @@ void dccp_li_update_li(struct sock *sk, struct dccp_li_hist *li_hist,
314} 268}
315 269
316EXPORT_SYMBOL_GPL(dccp_li_update_li); 270EXPORT_SYMBOL_GPL(dccp_li_update_li);
271
272static __init int dccp_li_init(void)
273{
274 dccp_li_cachep = kmem_cache_create("dccp_li_hist",
275 sizeof(struct dccp_li_hist_entry),
276 0, SLAB_HWCACHE_ALIGN, NULL, NULL);
277 return dccp_li_cachep == NULL ? -ENOBUFS : 0;
278}
279
280static __exit void dccp_li_exit(void)
281{
282 kmem_cache_destroy(dccp_li_cachep);
283}
284
285module_init(dccp_li_init);
286module_exit(dccp_li_exit);
diff --git a/net/dccp/ccids/lib/loss_interval.h b/net/dccp/ccids/lib/loss_interval.h
index 8d3c9bfa4915..f35c11100fc6 100644
--- a/net/dccp/ccids/lib/loss_interval.h
+++ b/net/dccp/ccids/lib/loss_interval.h
@@ -19,13 +19,6 @@
19 19
20#define DCCP_LI_HIST_IVAL_F_LENGTH 8 20#define DCCP_LI_HIST_IVAL_F_LENGTH 8
21 21
22struct dccp_li_hist {
23 struct kmem_cache *dccplih_slab;
24};
25
26extern struct dccp_li_hist *dccp_li_hist_new(const char *name);
27extern void dccp_li_hist_delete(struct dccp_li_hist *hist);
28
29struct dccp_li_hist_entry { 22struct dccp_li_hist_entry {
30 struct list_head dccplih_node; 23 struct list_head dccplih_node;
31 u64 dccplih_seqno:48, 24 u64 dccplih_seqno:48,
@@ -33,12 +26,11 @@ struct dccp_li_hist_entry {
33 u32 dccplih_interval; 26 u32 dccplih_interval;
34}; 27};
35 28
36extern void dccp_li_hist_purge(struct dccp_li_hist *hist, 29extern void dccp_li_hist_purge(struct list_head *list);
37 struct list_head *list);
38 30
39extern u32 dccp_li_hist_calc_i_mean(struct list_head *list); 31extern u32 dccp_li_hist_calc_i_mean(struct list_head *list);
40 32
41extern void dccp_li_update_li(struct sock *sk, struct dccp_li_hist *li_hist, 33extern void dccp_li_update_li(struct sock *sk,
42 struct list_head *li_hist_list, 34 struct list_head *li_hist_list,
43 struct list_head *hist_list, 35 struct list_head *hist_list,
44 struct timeval *last_feedback, u16 s, 36 struct timeval *last_feedback, u16 s,