On 20 March 2008 14:56:02 Marcin Owsiany wrote:
> On Thu, Mar 20, 2008 at 10:20:12AM +0000, Marcin Owsiany wrote:
> > Now that I at least know what is going on, I'm going to tweak the patch
> > and try the window size patch.
>
> Unfortunately, using the 028.51.3 patch does not help.
>
> kernel/ub/ub_net.c: In function ‘ub_sock_tcp_update_rcvbuf’:
> kernel/ub/ub_net.c:811: warning: initialization from incompatible pointer type
> kernel/ub/ub_net.c:821: error: dereferencing pointer to incomplete type
> kernel/ub/ub_net.c:822: error: dereferencing pointer to incomplete type
>
> Attaching the ub_net.c file it tried to compile.
>
Try attached patch again, please.
--
Thank,
Vitaliy Gusev
diff --git a/include/net/tcp.h b/include/net/tcp.h
index f858278..4550c25 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -968,8 +968,9 @@ static inline int tcp_win_from_space(int space)
/* Note: caller must be prepared to deal with negative returns */
static inline int tcp_space(const struct sock *sk)
{
- return tcp_win_from_space(sk->sk_rcvbuf -
- atomic_read(&sk->sk_rmem_alloc));
+ int ub_tcp_rcvbuf = (int) sock_bc(sk)->ub_tcp_rcvbuf;
+ return tcp_win_from_space(min(sk->sk_rcvbuf, ub_tcp_rcvbuf)
+ - atomic_read(&sk->sk_rmem_alloc));
}
static inline int tcp_full_space(const struct sock *sk)
diff --git a/include/ub/beancounter.h b/include/ub/beancounter.h
index d984883..c204e15 100644
--- a/include/ub/beancounter.h
+++ b/include/ub/beancounter.h
@@ -151,6 +151,8 @@ struct sock_private {
unsigned long ubp_rmem_thres;
unsigned long ubp_wmem_pressure;
unsigned long ubp_maxadvmss;
+ /* Total size of all advertised receive windows for all tcp sockets */
+ unsigned long ubp_rcv_wnd;
unsigned long ubp_rmem_pressure;
int ubp_tw_count;
#define UB_RMEM_EXPAND 0
@@ -218,6 +220,7 @@ struct user_beancounter
struct sock_private spriv;
#define ub_rmem_thres spriv.ubp_rmem_thres
#define ub_maxadvmss spriv.ubp_maxadvmss
+#define ub_rcv_wnd spriv.ubp_rcv_wnd
#define ub_rmem_pressure spriv.ubp_rmem_pressure
#define ub_wmem_pressure spriv.ubp_wmem_pressure
#define ub_tcp_sk_list spriv.ubp_tcp_socks
diff --git a/include/ub/ub_sk.h b/include/ub/ub_sk.h
index 45f29be..1969593 100644
--- a/include/ub/ub_sk.h
+++ b/include/ub/ub_sk.h
@@ -34,6 +34,8 @@ struct sock_beancounter {
*/
unsigned long poll_reserv;
unsigned long forw_space;
+ unsigned long ub_tcp_rcvbuf;
+ unsigned long ub_rcv_wnd_old;
/* fields below are protected by bc spinlock */
unsigned long ub_waitspc; /* space waiting for */
unsigned long ub_wcharged;
diff --git a/kernel/ub/ub_net.c b/kernel/ub/ub_net.c
index fb2ac24..bfe925e 100644
--- a/kernel/ub/ub_net.c
+++ b/kernel/ub/ub_net.c
@@ -424,6 +424,7 @@ static int __sock_charge(struct sock *sk, int res)
added_reserv = 0;
added_forw = 0;
+ skbc->ub_rcv_wnd_old = 0;
if (res == UB_NUMTCPSOCK) {
added_reserv = skb_charge_size(MAX_TCP_HEADER +
1500 - sizeof(struct iphdr) -
@@ -443,6 +444,7 @@ static int __sock_charge(struct sock *sk, int res)
added_forw = 0;
}
skbc->forw_space = added_forw;
+ skbc->ub_tcp_rcvbuf = added_forw + SK_STREAM_MEM_QUANTUM;
}
spin_unlock_irqrestore(&ub->ub_lock, flags);
@@ -533,6 +535,7 @@ void ub_sock_uncharge(struct sock *sk)
skbc->ub_wcharged, skbc->ub, skbc->ub->ub_uid);
skbc->poll_reserv = 0;
skbc->forw_space = 0;
+ ub->ub_rcv_wnd -= is_tcp_sock ? tcp_sk(sk)->rcv_wnd : 0;
spin_unlock_irqrestore(&ub->ub_lock, flags);
uncharge_beancounter_notop(skbc->ub,
@@ -793,6 +796,44 @@ static void ub_sockrcvbuf_uncharge(struct sk_buff *skb)
* UB_TCPRCVBUF
*/
+/*
+ * UBC TCP window management mechanism.
+ * Every socket may consume no more than sock_quantum.
+ * sock_quantum depends on space available and ub_parms[UB_NUMTCPSOCK].held.
+ */
+static void ub_sock_tcp_update_rcvbuf(struct user_beancounter *ub,
+ struct sock *sk)
+{
+ unsigned long allowed;
+ unsigned long reserved;
+ unsigned long available;
+ unsigned long sock_quantum;
+ struct tcp_sock *tp = tcp_sk(sk);
+ struct sock_beancounter *skbc;
+ skbc = sock_bc(sk);
+
+ if( ub->ub_parms[UB_NUMTCPSOCK].limit * ub->ub_maxadvmss
+ > ub->ub_parms[UB_TCPRCVBUF].limit) {
+ /* this is defenitly shouldn't happend */
+ return;
+ }
+ allowed = ub->ub_parms[UB_TCPRCVBUF].barrier;
+ ub->ub_rcv_wnd += (tp->rcv_wnd - skbc->ub_rcv_wnd_old);
+ skbc->ub_rcv_wnd_old = tp->rcv_wnd;
+ reserved = ub->ub_parms[UB_TCPRCVBUF].held + ub->ub_rcv_wnd;
+ available = (allowed < reserved)?
+ 0:allowed - reserved;
+ sock_quantum = max(allowed / ub->ub_parms[UB_NUMTCPSOCK].held,
+ ub->ub_maxadvmss);
+ if ( skbc->ub_tcp_rcvbuf > sock_quantum) {
+ skbc->ub_tcp_rcvbuf = sock_quantum;
+ } else {
+ skbc->ub_tcp_rcvbuf += min(sock_quantum - skbc->ub_tcp_rcvbuf,
+ available);
+ }
+
+}
+
int ub_sock_tcp_chargerecv(struct sock *sk, struct sk_buff *skb,
enum ub_severity strict)
{
@@ -829,7 +870,9 @@ int ub_sock_tcp_chargerecv(struct sock *sk, struct sk_buff *skb,
retval = 0;
ub = top_beancounter(sock_bc(sk)->ub);
spin_lock_irqsave(&ub->ub_lock, flags);
+ ub_sock_tcp_update_rcvbuf(ub, sk);
ub->ub_parms[UB_TCPRCVBUF].held += chargesize;
+ ub_sock_tcp_update_rcvbuf(ub, sk);
if (ub->ub_parms[UB_TCPRCVBUF].held >
ub->ub_parms[UB_TCPRCVBUF].barrier &&
strict != UB_FORCE)
_______________________________________________
Users mailing list
[email protected]
https://openvz.org/mailman/listinfo/users