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

Reply via email to