Skip to contentSkip to conversation

query: TCPCT setsockopt kmalloc's

DISCUSSION William Allen Simpson 2 participants 2 messages Oct 6, 2009

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

On both the client and server side, the setsockopt does a kmalloc(). Only once per connect on the client side, once per listen on the server side.

However, after Miller's expressed concern, it seems possible to reorganize the code to do the kmalloc() before the lock_sock(). Does that mean that it should be GFP_KERNEL? Or should it still be GFP_ATOMIC?

[Not that anybody cares, but based on recent discussion on the list about internal kernel coding standards, I've changed Adam's old sizeof(struct) to sizeof(*tcvp). Previously, I was trying to make as few changes as possible, thinking everything was already correct.]

===
new:

+ /* Allocate ancillary memory before locking.
+ */
+ if ((0 < tcd.tcpcd_used
...
+ && NULL == (tcvp = kmalloc(sizeof(*tcvp) + tcd.tcpcd_used,
+ GFP_KERNEL))) {
+ return -ENOMEM;
+ }
+
+ lock_sock(sk);
...
+ } else {
+ if (unlikely(NULL != tp->cookie_values)) {
+ kref_put(&tp->cookie_values->kref,
+ tcp_cookie_values_release);
+ }
+ kref_init(&tcvp->kref);
...
+ tp->cookie_values = tcvp;
+ }
+
+ release_sock(sk);
+ return err;

===
old:

+ lock_sock(sk);
...
+ } else if (NULL != (tsdplp =
+ kmalloc(sizeof(struct tcp_s_data_payload)
+ + tcd.tcpcd_used,
+ GFP_ATOMIC))) {
+ if (unlikely(tp->s_data_payload)) {
+ kref_put(&tp->s_data_payload->kref,
+ tcp_s_data_payload_release);
+ }
+ kref_init(&tsdplp->kref);
...
+ tp->s_data_payload = tsdplp;
+ } else {
+ err = -ENOMEM;
+ }
+
+ release_sock(sk);
+ return err;

#1 lore raw
Quoted 2 lines · William Allen Simpson

On both the client and server side, the setsockopt does a kmalloc(). Only once per connect on the client side, once per listen on the server side.

But if server has to generate a random data for a connection, you'll have to clone the data to be able to give it at application request ?

Quoted 5 lines

However, after Miller's expressed concern, it seems possible to reorganize the code to do the kmalloc() before the lock_sock(). Does that mean that it
should be GFP_KERNEL? Or should it still be GFP_ATOMIC?

GFP_KERNEL is better in this context, it allows the requestor to sleep a bit if necessary.

Quoted 12 lines

[Not that anybody cares, but based on recent discussion on the list about internal kernel coding standards, I've changed Adam's old sizeof(struct) to sizeof(*tcvp). Previously, I was trying to make as few changes as possible, thinking everything was already correct.]

===
new:

Review

Quoted 3 lines
(quoted diff) +3 -0
+        /* Allocate ancillary memory before locking.
+         */
+        if ((0 < tcd.tcpcd_used

Ah, could you please reverse all your conditions ?

Their form are unusual in linux kernel.

if (tcd.tcpcd_used > 0)

Review

Quoted 6 lines

...

(quoted diff) +4 -0
+         && NULL == (tcvp = kmalloc(sizeof(*tcvp) + tcd.tcpcd_used,
+                        GFP_KERNEL))) {
+            return -ENOMEM;
+        }

tcvp = kmalloc(sizeof(*tcvp) + tcd.tcpcd_used, GFP_KERNEL)); if (tcvp == NULL) ...