All new accounts created on Gitlab now require administrator approval. If you invite any collaborators, please let Flux staff know so they can approve the accounts.

  1. 21 Sep, 2013 1 commit
  2. 27 Feb, 2013 1 commit
    • Sasha Levin's avatar
      hlist: drop the node parameter from iterators · b67bfe0d
      Sasha Levin authored
      I'm not sure why, but the hlist for each entry iterators were conceived
      
              list_for_each_entry(pos, head, member)
      
      The hlist ones were greedy and wanted an extra parameter:
      
              hlist_for_each_entry(tpos, pos, head, member)
      
      Why did they need an extra pos parameter? I'm not quite sure. Not only
      they don't really need it, it also prevents the iterator from looking
      exactly like the list iterator, which is unfortunate.
      
      Besides the semantic patch, there was some manual work required:
      
       - Fix up the actual hlist iterators in linux/list.h
       - Fix up the declaration of other iterators based on the hlist ones.
       - A very small amount of places were using the 'node' parameter, this
       was modified to use 'obj->member' instead.
       - Coccinelle didn't handle the hlist_for_each_entry_safe iterator
       properly, so those had to be fixed up manually.
      
      The semantic patch which is mostly the work of Peter Senna Tschudin is here:
      
      @@
      iterator name hlist_for_each_entry, hlist_for_each_entry_continue, hlist_for_each_entry_from, hlist_for_each_entry_rcu, hlist_for_each_entry_rcu_bh, hlist_for_each_entry_continue_rcu_bh, for_each_busy_worker, ax25_uid_for_each, ax25_for_each, inet_bind_bucket_for_each, sctp_for_each_hentry, sk_for_each, sk_for_each_rcu, sk_for_each_from, sk_for_each_safe, sk_for_each_bound, hlist_for_each_entry_safe, hlist_for_each_entry_continue_rcu, nr_neigh_for_each, nr_neigh_for_each_safe, nr_node_for_each, nr_node_for_each_safe, for_each_gfn_indirect_valid_sp, for_each_gfn_sp, for_each_host;
      
      type T;
      expression a,c,d,e;
      identifier b;
      statement S;
      @@
      
      -T b;
          <+... when != b
      (
      hlist_for_each_entry(a,
      - b,
      c, d) S
      |
      hlist_for_each_entry_continue(a,
      - b,
      c) S
      |
      hlist_for_each_entry_from(a,
      - b,
      c) S
      |
      hlist_for_each_entry_rcu(a,
      - b,
      c, d) S
      |
      hlist_for_each_entry_rcu_bh(a,
      - b,
      c, d) S
      |
      hlist_for_each_entry_continue_rcu_bh(a,
      - b,
      c) S
      |
      for_each_busy_worker(a, c,
      - b,
      d) S
      |
      ax25_uid_for_each(a,
      - b,
      c) S
      |
      ax25_for_each(a,
      - b,
      c) S
      |
      inet_bind_bucket_for_each(a,
      - b,
      c) S
      |
      sctp_for_each_hentry(a,
      - b,
      c) S
      |
      sk_for_each(a,
      - b,
      c) S
      |
      sk_for_each_rcu(a,
      - b,
      c) S
      |
      sk_for_each_from
      -(a, b)
      +(a)
      S
      + sk_for_each_from(a) S
      |
      sk_for_each_safe(a,
      - b,
      c, d) S
      |
      sk_for_each_bound(a,
      - b,
      c) S
      |
      hlist_for_each_entry_safe(a,
      - b,
      c, d, e) S
      |
      hlist_for_each_entry_continue_rcu(a,
      - b,
      c) S
      |
      nr_neigh_for_each(a,
      - b,
      c) S
      |
      nr_neigh_for_each_safe(a,
      - b,
      c, d) S
      |
      nr_node_for_each(a,
      - b,
      c) S
      |
      nr_node_for_each_safe(a,
      - b,
      c, d) S
      |
      - for_each_gfn_sp(a, c, d, b) S
      + for_each_gfn_sp(a, c, d) S
      |
      - for_each_gfn_indirect_valid_sp(a, c, d, b) S
      + for_each_gfn_indirect_valid_sp(a, c, d) S
      |
      for_each_host(a,
      - b,
      c) S
      |
      for_each_host_safe(a,
      - b,
      c, d) S
      |
      for_each_mesh_entry(a,
      - b,
      c, d) S
      )
          ...+>
      
      [akpm@linux-foundation.org: drop bogus change from net/ipv4/raw.c]
      [akpm@linux-foundation.org: drop bogus hunk from net/ipv6/raw.c]
      [akpm@linux-foundation.org: checkpatch fixes]
      [akpm@linux-foundation.org: fix warnings]
      [akpm@linux-foudnation.org: redo intrusive kvm changes]
      Tested-by: default avatarPeter Senna Tschudin <peter.senna@gmail.com>
      Acked-by: default avatarPaul E. McKenney <paulmck@linux.vnet.ibm.com>
      Signed-off-by: default avatarSasha Levin <sasha.levin@oracle.com>
      Cc: Wu Fengguang <fengguang.wu@intel.com>
      Cc: Marcelo Tosatti <mtosatti@redhat.com>
      Cc: Gleb Natapov <gleb@redhat.com>
      Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
      Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
      b67bfe0d
  3. 23 Jan, 2013 1 commit
    • Tom Herbert's avatar
      soreuseport: TCP/IPv4 implementation · da5e3630
      Tom Herbert authored
      Allow multiple listener sockets to bind to the same port.
      
      Motivation for soresuseport would be something like a web server
      binding to port 80 running with multiple threads, where each thread
      might have it's own listener socket.  This could be done as an
      alternative to other models: 1) have one listener thread which
      dispatches completed connections to workers. 2) accept on a single
      listener socket from multiple threads.  In case #1 the listener thread
      can easily become the bottleneck with high connection turn-over rate.
      In case #2, the proportion of connections accepted per thread tends
      to be uneven under high connection load (assuming simple event loop:
      while (1) { accept(); process() }, wakeup does not promote fairness
      among the sockets.  We have seen the  disproportion to be as high
      as 3:1 ratio between thread accepting most connections and the one
      accepting the fewest.  With so_reusport the distribution is
      uniform.
      Signed-off-by: default avatarTom Herbert <therbert@google.com>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      da5e3630
  4. 02 Dec, 2012 1 commit
  5. 30 Nov, 2012 1 commit
    • Eric Dumazet's avatar
      net: move inet_dport/inet_num in sock_common · ce43b03e
      Eric Dumazet authored
      commit 68835aba (net: optimize INET input path further)
      moved some fields used for tcp/udp sockets lookup in the first cache
      line of struct sock_common.
      
      This patch moves inet_dport/inet_num as well, filling a 32bit hole
      on 64 bit arches and reducing number of cache line misses in lookups.
      
      Also change INET_MATCH()/INET_TW_MATCH() to perform the ports match
      before addresses match, as this check is more discriminant.
      
      Remove the hash check from MATCH() macros because we dont need to
      re validate the hash value after taking a refcount on socket, and
      use likely/unlikely compiler hints, as the sk_hash/hash check
      makes the following conditional tests 100% predicted by cpu.
      
      Introduce skc_addrpair/skc_portpair pair values to better
      document the alignment requirements of the port/addr pairs
      used in the various MATCH() macros, and remove some casts.
      
      The namespace check can also be done at last.
      
      This slightly improves TCP/UDP lookup times.
      
      IP/TCP early demux needs inet->rx_dst_ifindex and
      TCP needs inet->min_ttl, lets group them together in same cache line.
      
      With help from Ben Hutchings & Joe Perches.
      
      Idea of this patch came after Ling Ma proposal to move skc_hash
      to the beginning of struct sock_common, and should allow him
      to submit a final version of his patch. My tests show an improvement
      doing so.
      Signed-off-by: default avatarEric Dumazet <edumazet@google.com>
      Cc: Ben Hutchings <bhutchings@solarflare.com>
      Cc: Joe Perches <joe@perches.com>
      Cc: Ling Ma <ling.ma.program@gmail.com>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      ce43b03e
  6. 19 Jun, 2012 1 commit
    • David S. Miller's avatar
      ipv4: Early TCP socket demux. · 41063e9d
      David S. Miller authored
      Input packet processing for local sockets involves two major demuxes.
      One for the route and one for the socket.
      
      But we can optimize this down to one demux for certain kinds of local
      sockets.
      
      Currently we only do this for established TCP sockets, but it could
      at least in theory be expanded to other kinds of connections.
      
      If a TCP socket is established then it's identity is fully specified.
      
      This means that whatever input route was used during the three-way
      handshake must work equally well for the rest of the connection since
      the keys will not change.
      
      Once we move to established state, we cache the receive packet's input
      route to use later.
      
      Like the existing cached route in sk->sk_dst_cache used for output
      packets, we have to check for route invalidations using dst->obsolete
      and dst->ops->check().
      
      Early demux occurs outside of a socket locked section, so when a route
      invalidation occurs we defer the fixup of sk->sk_rx_dst until we are
      actually inside of established state packet processing and thus have
      the socket locked.
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      41063e9d
  7. 26 Jul, 2011 1 commit
  8. 21 Oct, 2010 1 commit
  9. 08 Dec, 2009 1 commit
  10. 13 Nov, 2009 1 commit
  11. 18 Oct, 2009 1 commit
    • Eric Dumazet's avatar
      inet: rename some inet_sock fields · c720c7e8
      Eric Dumazet authored
      In order to have better cache layouts of struct sock (separate zones
      for rx/tx paths), we need this preliminary patch.
      
      Goal is to transfert fields used at lookup time in the first
      read-mostly cache line (inside struct sock_common) and move sk_refcnt
      to a separate cache line (only written by rx path)
      
      This patch adds inet_ prefix to daddr, rcv_saddr, dport, num, saddr,
      sport and id fields. This allows a future patch to define these
      fields as macros, like sk_refcnt, without name clashes.
      Signed-off-by: default avatarEric Dumazet <eric.dumazet@gmail.com>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      c720c7e8
  12. 13 Oct, 2009 1 commit
  13. 03 Jun, 2009 1 commit
  14. 01 Feb, 2009 1 commit
  15. 27 Jan, 2009 1 commit
    • Eric Dumazet's avatar
      net: wrong test in inet_ehash_locks_alloc() · 94cd3e6c
      Eric Dumazet authored
      In commit 9db66bdc (net: convert
      TCP/DCCP ehash rwlocks to spinlocks), I forgot to change one
      occurrence of rwlock_t to spinlock_t
      
      I believe sizeof(raw_spinlock_t) might be > 0 on !CONFIG_SMP if
      CONFIG_DEBUG_SPINLOCK while sizeof(raw_rwlock_t) should be 0 in this
      case.
      
      Fortunatly, CONFIG_DEBUG_SPINLOCK adds fields to both spinlock_t and
      rwlock_t, but at this might change in the future (being able to debug
      spinlocks but not rwlocks for example), better to be safe.
      Signed-off-by: default avatarEric Dumazet <dada1@cosmosbay.com>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      94cd3e6c
  16. 21 Jan, 2009 1 commit
    • Evgeniy Polyakov's avatar
      inet: Allowing more than 64k connections and heavily optimize bind(0) time. · a9d8f911
      Evgeniy Polyakov authored
      With simple extension to the binding mechanism, which allows to bind more
      than 64k sockets (or smaller amount, depending on sysctl parameters),
      we have to traverse the whole bind hash table to find out empty bucket.
      And while it is not a problem for example for 32k connections, bind()
      completion time grows exponentially (since after each successful binding
      we have to traverse one bucket more to find empty one) even if we start
      each time from random offset inside the hash table.
      
      So, when hash table is full, and we want to add another socket, we have
      to traverse the whole table no matter what, so effectivelly this will be
      the worst case performance and it will be constant.
      
      Attached picture shows bind() time depending on number of already bound
      sockets.
      
      Green area corresponds to the usual binding to zero port process, which
      turns on kernel port selection as described above. Red area is the bind
      process, when number of reuse-bound sockets is not limited by 64k (or
      sysctl parameters). The same exponential growth (hidden by the green
      area) before number of ports reaches sysctl limit.
      
      At this time bind hash table has exactly one reuse-enbaled socket in a
      bucket, but it is possible that they have different addresses. Actually
      kernel selects the first port to try randomly, so at the beginning bind
      will take roughly constant time, but with time number of port to check
      after random start will increase. And that will have exponential growth,
      but because of above random selection, not every next port selection
      will necessary take longer time than previous. So we have to consider
      the area below in the graph (if you could zoom it, you could find, that
      there are many different times placed there), so area can hide another.
      
      Blue area corresponds to the port selection optimization.
      
      This is rather simple design approach: hashtable now maintains (unprecise
      and racely updated) number of currently bound sockets, and when number
      of such sockets becomes greater than predefined value (I use maximum
      port range defined by sysctls), we stop traversing the whole bind hash
      table and just stop at first matching bucket after random start. Above
      limit roughly corresponds to the case, when bind hash table is full and
      we turned on mechanism of allowing to bind more reuse-enabled sockets,
      so it does not change behaviour of other sockets.
      Signed-off-by: default avatarEvgeniy Polyakov <zbr@ioremap.net>
      Tested-by: default avatarDenys Fedoryschenko <denys@visp.net.lb>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      a9d8f911
  17. 23 Nov, 2008 1 commit
    • Eric Dumazet's avatar
      net: Convert TCP/DCCP listening hash tables to use RCU · c25eb3bf
      Eric Dumazet authored
      This is the last step to be able to perform full RCU lookups
      in __inet_lookup() : After established/timewait tables, we
      add RCU lookups to listening hash table.
      
      The only trick here is that a socket of a given type (TCP ipv4,
      TCP ipv6, ...) can now flight between two different tables
      (established and listening) during a RCU grace period, so we
      must use different 'nulls' end-of-chain values for two tables.
      
      We define a large value :
      
      #define LISTENING_NULLS_BASE (1U << 29)
      
      So that slots in listening table are guaranteed to have different
      end-of-chain values than slots in established table. A reader can
      still detect it finished its lookup in the right chain.
      Signed-off-by: default avatarEric Dumazet <dada1@cosmosbay.com>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      c25eb3bf
  18. 21 Nov, 2008 1 commit
  19. 20 Nov, 2008 2 commits
  20. 16 Nov, 2008 1 commit
    • Eric Dumazet's avatar
      net: Convert TCP & DCCP hash tables to use RCU / hlist_nulls · 3ab5aee7
      Eric Dumazet authored
      RCU was added to UDP lookups, using a fast infrastructure :
      - sockets kmem_cache use SLAB_DESTROY_BY_RCU and dont pay the
        price of call_rcu() at freeing time.
      - hlist_nulls permits to use few memory barriers.
      
      This patch uses same infrastructure for TCP/DCCP established
      and timewait sockets.
      
      Thanks to SLAB_DESTROY_BY_RCU, no slowdown for applications
      using short lived TCP connections. A followup patch, converting
      rwlocks to spinlocks will even speedup this case.
      
      __inet_lookup_established() is pretty fast now we dont have to
      dirty a contended cache line (read_lock/read_unlock)
      
      Only established and timewait hashtable are converted to RCU
      (bind table and listen table are still using traditional locking)
      Signed-off-by: default avatarEric Dumazet <dada1@cosmosbay.com>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      3ab5aee7
  21. 12 Nov, 2008 1 commit
  22. 07 Oct, 2008 2 commits
  23. 16 Jun, 2008 3 commits
  24. 18 Apr, 2008 2 commits
  25. 25 Mar, 2008 1 commit
  26. 22 Mar, 2008 1 commit
    • Pavel Emelyanov's avatar
      [SOCK]: Add udp_hash member to struct proto. · 39d8cda7
      Pavel Emelyanov authored
      Inspired by the commit ab1e0a13 ([SOCK] proto: Add hashinfo member to 
      struct proto) from Arnaldo, I made similar thing for UDP/-Lite IPv4 
      and -v6 protocols.
      
      The result is not that exciting, but it removes some levels of
      indirection in udpxxx_get_port and saves some space in code and text.
      
      The first step is to union existing hashinfo and new udp_hash on the
      struct proto and give a name to this union, since future initialization 
      of tcpxxx_prot, dccp_vx_protinfo and udpxxx_protinfo will cause gcc 
      warning about inability to initialize anonymous member this way.
      Signed-off-by: default avatarPavel Emelyanov <xemul@openvz.org>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      39d8cda7
  27. 05 Feb, 2008 1 commit
  28. 03 Feb, 2008 1 commit
    • Arnaldo Carvalho de Melo's avatar
      [SOCK] proto: Add hashinfo member to struct proto · ab1e0a13
      Arnaldo Carvalho de Melo authored
      This way we can remove TCP and DCCP specific versions of
      
      sk->sk_prot->get_port: both v4 and v6 use inet_csk_get_port
      sk->sk_prot->hash:     inet_hash is directly used, only v6 need
                             a specific version to deal with mapped sockets
      sk->sk_prot->unhash:   both v4 and v6 use inet_hash directly
      
      struct inet_connection_sock_af_ops also gets a new member, bind_conflict, so
      that inet_csk_get_port can find the per family routine.
      
      Now only the lookup routines receive as a parameter a struct inet_hashtable.
      
      With this we further reuse code, reducing the difference among INET transport
      protocols.
      
      Eventually work has to be done on UDP and SCTP to make them share this
      infrastructure and get as a bonus inet_diag interfaces so that iproute can be
      used with these protocols.
      
      net-2.6/net/ipv4/inet_hashtables.c:
        struct proto			     |   +8
        struct inet_connection_sock_af_ops |   +8
       2 structs changed
        __inet_hash_nolisten               |  +18
        __inet_hash                        | -210
        inet_put_port                      |   +8
        inet_bind_bucket_create            |   +1
        __inet_hash_connect                |   -8
       5 functions changed, 27 bytes added, 218 bytes removed, diff: -191
      
      net-2.6/net/core/sock.c:
        proto_seq_show                     |   +3
       1 function changed, 3 bytes added, diff: +3
      
      net-2.6/net/ipv4/inet_connection_sock.c:
        inet_csk_get_port                  |  +15
       1 function changed, 15 bytes added, diff: +15
      
      net-2.6/net/ipv4/tcp.c:
        tcp_set_state                      |   -7
       1 function changed, 7 bytes removed, diff: -7
      
      net-2.6/net/ipv4/tcp_ipv4.c:
        tcp_v4_get_port                    |  -31
        tcp_v4_hash                        |  -48
        tcp_v4_destroy_sock                |   -7
        tcp_v4_syn_recv_sock               |   -2
        tcp_unhash                         | -179
       5 functions changed, 267 bytes removed, diff: -267
      
      net-2.6/net/ipv6/inet6_hashtables.c:
        __inet6_hash |   +8
       1 function changed, 8 bytes added, diff: +8
      
      net-2.6/net/ipv4/inet_hashtables.c:
        inet_unhash                        | +190
        inet_hash                          | +242
       2 functions changed, 432 bytes added, diff: +432
      
      vmlinux:
       16 functions changed, 485 bytes added, 492 bytes removed, diff: -7
      
      /home/acme/git/net-2.6/net/ipv6/tcp_ipv6.c:
        tcp_v6_get_port                    |  -31
        tcp_v6_hash                        |   -7
        tcp_v6_syn_recv_sock               |   -9
       3 functions changed, 47 bytes removed, diff: -47
      
      /home/acme/git/net-2.6/net/dccp/proto.c:
        dccp_destroy_sock                  |   -7
        dccp_unhash                        | -179
        dccp_hash                          |  -49
        dccp_set_state                     |   -7
        dccp_done                          |   +1
       5 functions changed, 1 bytes added, 242 bytes removed, diff: -241
      
      /home/acme/git/net-2.6/net/dccp/ipv4.c:
        dccp_v4_get_port                   |  -31
        dccp_v4_request_recv_sock          |   -2
       2 functions changed, 33 bytes removed, diff: -33
      
      /home/acme/git/net-2.6/net/dccp/ipv6.c:
        dccp_v6_get_port                   |  -31
        dccp_v6_hash                       |   -7
        dccp_v6_request_recv_sock          |   +5
       3 functions changed, 5 bytes added, 38 bytes removed, diff: -33
      Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      ab1e0a13
  29. 31 Jan, 2008 3 commits
  30. 28 Jan, 2008 3 commits
    • Eric Dumazet's avatar
      [NET]: prot_inuse cleanups and optimizations · 65f76517
      Eric Dumazet authored
      1) Cleanups (all functions are prefixed by sock_prot_inuse)
      
      sock_prot_inc_use(prot) -> sock_prot_inuse_add(prot,-1)
      sock_prot_dec_use(prot) -> sock_prot_inuse_add(prot,-1)
      sock_prot_inuse()       -> sock_prot_inuse_get()
      
      New functions :
      
      sock_prot_inuse_init() and sock_prot_inuse_free() to abstract pcounter use.
      
      2) if CONFIG_PROC_FS=n, we can zap 'inuse' member from "struct proto",
      since nobody wants to read the inuse value.
      
      This saves 1372 bytes on i386/SMP and some cpu cycles.
      Signed-off-by: default avatarEric Dumazet <dada1@cosmosbay.com>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      65f76517
    • Pavel Emelyanov's avatar
      [INET]: Uninline the __inet_lookup_established function. · 77a5ba55
      Pavel Emelyanov authored
      This is -700 bytes from the net/ipv4/built-in.o
      
      add/remove: 1/0 grow/shrink: 1/3 up/down: 340/-1040 (-700)
      function                                     old     new   delta
      __inet_lookup_established                      -     339    +339
      tcp_sacktag_write_queue                     2254    2255      +1
      tcp_v4_err                                  1304     973    -331
      tcp_v4_rcv                                  2089    1744    -345
      tcp_v4_do_rcv                                826     462    -364
      
      Exporting is for dccp module (used via e.g. inet_lookup).
      Signed-off-by: default avatarPavel Emelyanov <xemul@openvz.org>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      77a5ba55
    • Pavel Emelyanov's avatar
      [INET]: Uninline the __inet_hash function. · 152da81d
      Pavel Emelyanov authored
      This one is used in quite many places in the networking code and
      seems to big to be inline.
      
      After the patch net/ipv4/build-in.o loses ~650 bytes:
      add/remove: 2/0 grow/shrink: 0/5 up/down: 461/-1114 (-653)
      function                                     old     new   delta
      __inet_hash_nolisten                           -     282    +282
      __inet_hash                                    -     179    +179
      tcp_sacktag_write_queue                     2255    2254      -1
      __inet_lookup_listener                       284     274     -10
      tcp_v4_syn_recv_sock                         755     493    -262
      tcp_v4_hash                                  389      35    -354
      inet_hash_connect                           1086     599    -487
      
      This version addresses the issue pointed by Eric, that
      while being inline this function was optimized by gcc
      in respect to the 'listen_possible' argument.
      Signed-off-by: default avatarPavel Emelyanov <xemul@openvz.org>
      Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
      152da81d
  31. 26 Nov, 2007 1 commit
    • Pavel Emelyanov's avatar
      [IPV4]: Fix memory leak in inet_hashtables.h when NUMA is on · 218ad12f
      Pavel Emelyanov authored
      The inet_ehash_locks_alloc() looks like this:
      
      #ifdef CONFIG_NUMA
      	if (size > PAGE_SIZE)
      		x = vmalloc(...);
      	else
      #endif
      		x = kmalloc(...);
      
      Unlike it, the inet_ehash_locks_alloc() looks like this:
      
      #ifdef CONFIG_NUMA
      	if (size > PAGE_SIZE)
      		vfree(x);
      	else
      #else
      		kfree(x);
      #endif
      
      The error is obvious - if the NUMA is on and the size
      is less than the PAGE_SIZE we leak the pointer (kfree is
      inside the #else branch).
      
      Compiler doesn't warn us because after the kfree(x) there's
      a "x = NULL" assignment, so here's another (minor?) bug: we 
      don't set x to NULL under certain circumstances.
      
      Boring explanation, I know... Patch explains it better.
      Signed-off-by: default avatarPavel Emelyanov <xemul@openvz.org>
      Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
      218ad12f