Merge tag 'random-6.1-rc1-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 16 Oct 2022 22:27:07 +0000 (15:27 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 16 Oct 2022 22:27:07 +0000 (15:27 -0700)
Pull more random number generator updates from Jason Donenfeld:
 "This time with some large scale treewide cleanups.

  The intent of this pull is to clean up the way callers fetch random
  integers. The current rules for doing this right are:

   - If you want a secure or an insecure random u64, use get_random_u64()

   - If you want a secure or an insecure random u32, use get_random_u32()

     The old function prandom_u32() has been deprecated for a while
     now and is just a wrapper around get_random_u32(). Same for
     get_random_int().

   - If you want a secure or an insecure random u16, use get_random_u16()

   - If you want a secure or an insecure random u8, use get_random_u8()

   - If you want secure or insecure random bytes, use get_random_bytes().

     The old function prandom_bytes() has been deprecated for a while
     now and has long been a wrapper around get_random_bytes()

   - If you want a non-uniform random u32, u16, or u8 bounded by a
     certain open interval maximum, use prandom_u32_max()

     I say "non-uniform", because it doesn't do any rejection sampling
     or divisions. Hence, it stays within the prandom_*() namespace, not
     the get_random_*() namespace.

     I'm currently investigating a "uniform" function for 6.2. We'll see
     what comes of that.

  By applying these rules uniformly, we get several benefits:

   - By using prandom_u32_max() with an upper-bound that the compiler
     can prove at compile-time is ≤65536 or ≤256, internally
     get_random_u16() or get_random_u8() is used, which wastes fewer
     batched random bytes, and hence has higher throughput.

   - By using prandom_u32_max() instead of %, when the upper-bound is
     not a constant, division is still avoided, because
     prandom_u32_max() uses a faster multiplication-based trick instead.

   - By using get_random_u16() or get_random_u8() in cases where the
     return value is intended to indeed be a u16 or a u8, we waste fewer
     batched random bytes, and hence have higher throughput.

  This series was originally done by hand while I was on an airplane
  without Internet. Later, Kees and I worked on retroactively figuring
  out what could be done with Coccinelle and what had to be done
  manually, and then we split things up based on that.

  So while this touches a lot of files, the actual amount of code that's
  hand fiddled is comfortably small"

* tag 'random-6.1-rc1-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/crng/random:
  prandom: remove unused functions
  treewide: use get_random_bytes() when possible
  treewide: use get_random_u32() when possible
  treewide: use get_random_{u8,u16}() when possible, part 2
  treewide: use get_random_{u8,u16}() when possible, part 1
  treewide: use prandom_u32_max() when possible, part 2
  treewide: use prandom_u32_max() when possible, part 1

12 files changed:
1  2 
arch/arm/kernel/process.c
arch/arm64/kernel/process.c
arch/parisc/kernel/process.c
arch/powerpc/kernel/process.c
fs/ceph/inode.c
fs/ubifs/journal.c
mm/kasan/kasan_test.c
mm/slab.c
net/ipv4/tcp_cdg.c
net/ipv4/udp.c
net/sunrpc/xprt.c
net/sunrpc/xprtsock.c

index fc30df88ffbe5ca54134a5d550b5324776db933b,129279b33b1d4c4c6b29a5a23c8885a4b13b1f06..a2b31d91a1b6e32091edd704310376112d9fbda2
@@@ -232,6 -232,10 +232,6 @@@ void flush_thread(void
        thread_notify(THREAD_NOTIFY_FLUSH, thread);
  }
  
 -void release_thread(struct task_struct *dead_task)
 -{
 -}
 -
  asmlinkage void ret_from_fork(void) __asm__("ret_from_fork");
  
  int copy_thread(struct task_struct *p, const struct kernel_clone_args *args)
@@@ -371,7 -375,7 +371,7 @@@ static unsigned long sigpage_addr(cons
  
        slots = ((last - first) >> PAGE_SHIFT) + 1;
  
-       offset = get_random_int() % slots;
+       offset = prandom_u32_max(slots);
  
        addr = first + (offset << PAGE_SHIFT);
  
index 9015f49c206efad37e131d3ea8635c3497cfa81a,87203429f80233c4c30e4406ba442978f97f401a..044a7d7f1f6adb49326129cfb8724afe55f1b5d0
@@@ -279,6 -279,10 +279,6 @@@ void flush_thread(void
        flush_tagged_addr_state();
  }
  
 -void release_thread(struct task_struct *dead_task)
 -{
 -}
 -
  void arch_release_task_struct(struct task_struct *tsk)
  {
        fpsimd_release_task(tsk);
@@@ -591,7 -595,7 +591,7 @@@ unsigned long __get_wchan(struct task_s
  unsigned long arch_align_stack(unsigned long sp)
  {
        if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
-               sp -= get_random_int() & ~PAGE_MASK;
+               sp -= prandom_u32_max(PAGE_SIZE);
        return sp & ~0xf;
  }
  
index 3db0e97e6c066d0ef6bf7c0c568556bf7965b4e6,18c4f0e3e906c257f5bc50355747201185aa367c..c4f8374c7018d644f3e1e06f11f50922f490466c
@@@ -146,6 -146,10 +146,6 @@@ void flush_thread(void
        */
  }
  
 -void release_thread(struct task_struct *dead_task)
 -{
 -}
 -
  /*
   * Idle thread support
   *
@@@ -284,7 -288,7 +284,7 @@@ __get_wchan(struct task_struct *p
  
  static inline unsigned long brk_rnd(void)
  {
-       return (get_random_int() & BRK_RND_MASK) << PAGE_SHIFT;
+       return (get_random_u32() & BRK_RND_MASK) << PAGE_SHIFT;
  }
  
  unsigned long arch_randomize_brk(struct mm_struct *mm)
index 40834ef84f0c58b9df4cc67bd293e8d589121f34,599391c235738b05ea3f1e6bec1ae011b71a50a5..67da147fe34dc5cf2558f6304f87b8c20d0f3d45
@@@ -1655,6 -1655,11 +1655,6 @@@ EXPORT_SYMBOL_GPL(set_thread_tidr)
  
  #endif /* CONFIG_PPC64 */
  
 -void
 -release_thread(struct task_struct *t)
 -{
 -}
 -
  /*
   * this gets called so that we can store coprocessor state into memory and
   * copy the current task into the new thread.
@@@ -2303,6 -2308,6 +2303,6 @@@ void notrace __ppc64_runlatch_off(void
  unsigned long arch_align_stack(unsigned long sp)
  {
        if (!(current->personality & ADDR_NO_RANDOMIZE) && randomize_va_space)
-               sp -= get_random_int() & ~PAGE_MASK;
+               sp -= prandom_u32_max(PAGE_SIZE);
        return sp & ~0xf;
  }
diff --combined fs/ceph/inode.c
index 9ebb7cee7978977f79a13ebb49bf6719a67adef8,f0c6e7e7b92b961dff95fc986312b48cf07360ac..4af5e55abc1586748882e54e3da3660d8444aaab
@@@ -362,7 -362,7 +362,7 @@@ static int ceph_fill_fragtree(struct in
        if (nsplits != ci->i_fragtree_nsplits) {
                update = true;
        } else if (nsplits) {
-               i = prandom_u32() % nsplits;
+               i = prandom_u32_max(nsplits);
                id = le32_to_cpu(fragtree->splits[i].frag);
                if (!__ceph_find_frag(ci, id))
                        update = true;
@@@ -2192,7 -2192,6 +2192,7 @@@ int __ceph_setattr(struct inode *inode
                inode_dirty_flags = __ceph_mark_dirty_caps(ci, dirtied,
                                                           &prealloc_cf);
                inode->i_ctime = attr->ia_ctime;
 +              inode_inc_iversion_raw(inode);
        }
  
        release &= issued;
@@@ -2357,7 -2356,6 +2357,7 @@@ int ceph_do_getvxattr(struct inode *ino
                goto out;
        }
  
 +      req->r_feature_needed = CEPHFS_FEATURE_OP_GETVXATTR;
        req->r_path2 = kstrdup(name, GFP_NOFS);
        if (!req->r_path2) {
                err = -ENOMEM;
@@@ -2449,7 -2447,6 +2449,7 @@@ int ceph_getattr(struct user_namespace 
                 struct kstat *stat, u32 request_mask, unsigned int flags)
  {
        struct inode *inode = d_inode(path->dentry);
 +      struct super_block *sb = inode->i_sb;
        struct ceph_inode_info *ci = ceph_inode(inode);
        u32 valid_mask = STATX_BASIC_STATS;
        int err = 0;
        }
  
        if (ceph_snap(inode) == CEPH_NOSNAP)
 -              stat->dev = inode->i_sb->s_dev;
 +              stat->dev = sb->s_dev;
        else
                stat->dev = ci->i_snapid_map ? ci->i_snapid_map->dev : 0;
  
        if (S_ISDIR(inode->i_mode)) {
 -              if (ceph_test_mount_opt(ceph_sb_to_client(inode->i_sb),
 -                                      RBYTES))
 +              if (ceph_test_mount_opt(ceph_sb_to_client(sb), RBYTES)) {
                        stat->size = ci->i_rbytes;
 -              else
 +              } else if (ceph_snap(inode) == CEPH_SNAPDIR) {
 +                      struct ceph_inode_info *pci;
 +                      struct ceph_snap_realm *realm;
 +                      struct inode *parent;
 +
 +                      parent = ceph_lookup_inode(sb, ceph_ino(inode));
 +                      if (!parent)
 +                              return PTR_ERR(parent);
 +
 +                      pci = ceph_inode(parent);
 +                      spin_lock(&pci->i_ceph_lock);
 +                      realm = pci->i_snap_realm;
 +                      if (realm)
 +                              stat->size = realm->num_snaps;
 +                      else
 +                              stat->size = 0;
 +                      spin_unlock(&pci->i_ceph_lock);
 +                      iput(parent);
 +              } else {
                        stat->size = ci->i_files + ci->i_subdirs;
 +              }
                stat->blocks = 0;
                stat->blksize = 65536;
                /*
diff --combined fs/ubifs/journal.c
index 2b1d7c4297bf2f3631d87609d3f54530e4f947c5,4619652046cf839170e44797b140124571484087..d02509920bafadd9897c3c4fece885d3bc1efed9
@@@ -503,7 -503,7 +503,7 @@@ static void mark_inode_clean(struct ubi
  static void set_dent_cookie(struct ubifs_info *c, struct ubifs_dent_node *dent)
  {
        if (c->double_hash)
-               dent->cookie = (__force __le32) prandom_u32();
+               dent->cookie = (__force __le32) get_random_u32();
        else
                dent->cookie = 0;
  }
@@@ -1472,25 -1472,23 +1472,25 @@@ out_free
   * @block: data block number
   * @dn: data node to re-compress
   * @new_len: new length
 + * @dn_size: size of the data node @dn in memory
   *
   * This function is used when an inode is truncated and the last data node of
   * the inode has to be re-compressed/encrypted and re-written.
   */
  static int truncate_data_node(const struct ubifs_info *c, const struct inode *inode,
                              unsigned int block, struct ubifs_data_node *dn,
 -                            int *new_len)
 +                            int *new_len, int dn_size)
  {
        void *buf;
 -      int err, dlen, compr_type, out_len, old_dlen;
 +      int err, dlen, compr_type, out_len, data_size;
  
        out_len = le32_to_cpu(dn->size);
        buf = kmalloc_array(out_len, WORST_COMPR_FACTOR, GFP_NOFS);
        if (!buf)
                return -ENOMEM;
  
 -      dlen = old_dlen = le32_to_cpu(dn->ch.len) - UBIFS_DATA_NODE_SZ;
 +      dlen = le32_to_cpu(dn->ch.len) - UBIFS_DATA_NODE_SZ;
 +      data_size = dn_size - UBIFS_DATA_NODE_SZ;
        compr_type = le16_to_cpu(dn->compr_type);
  
        if (IS_ENCRYPTED(inode)) {
        }
  
        if (IS_ENCRYPTED(inode)) {
 -              err = ubifs_encrypt(inode, dn, out_len, &old_dlen, block);
 +              err = ubifs_encrypt(inode, dn, out_len, &data_size, block);
                if (err)
                        goto out;
  
 -              out_len = old_dlen;
 +              out_len = data_size;
        } else {
                dn->compr_size = 0;
        }
@@@ -1552,7 -1550,6 +1552,7 @@@ int ubifs_jnl_truncate(struct ubifs_inf
        struct ubifs_trun_node *trun;
        struct ubifs_data_node *dn;
        int err, dlen, len, lnum, offs, bit, sz, sync = IS_SYNC(inode);
 +      int dn_size;
        struct ubifs_inode *ui = ubifs_inode(inode);
        ino_t inum = inode->i_ino;
        unsigned int blk;
        ubifs_assert(c, S_ISREG(inode->i_mode));
        ubifs_assert(c, mutex_is_locked(&ui->ui_mutex));
  
 -      sz = UBIFS_TRUN_NODE_SZ + UBIFS_INO_NODE_SZ +
 -           UBIFS_MAX_DATA_NODE_SZ * WORST_COMPR_FACTOR;
 +      dn_size = COMPRESSED_DATA_NODE_BUF_SZ;
  
 -      sz += ubifs_auth_node_sz(c);
 +      if (IS_ENCRYPTED(inode))
 +              dn_size += UBIFS_CIPHER_BLOCK_SIZE;
 +
 +      sz =  UBIFS_TRUN_NODE_SZ + UBIFS_INO_NODE_SZ +
 +              dn_size + ubifs_auth_node_sz(c);
  
        ino = kmalloc(sz, GFP_NOFS);
        if (!ino)
                        if (dn_len <= 0 || dn_len > UBIFS_BLOCK_SIZE) {
                                ubifs_err(c, "bad data node (block %u, inode %lu)",
                                          blk, inode->i_ino);
 -                              ubifs_dump_node(c, dn, sz - UBIFS_INO_NODE_SZ -
 -                                              UBIFS_TRUN_NODE_SZ);
 +                              ubifs_dump_node(c, dn, dn_size);
                                goto out_free;
                        }
  
                        if (dn_len <= dlen)
                                dlen = 0; /* Nothing to do */
                        else {
 -                              err = truncate_data_node(c, inode, blk, dn, &dlen);
 +                              err = truncate_data_node(c, inode, blk, dn,
 +                                              &dlen, dn_size);
                                if (err)
                                        goto out_free;
                        }
diff --combined mm/kasan/kasan_test.c
index 57e4c72aa8bd2634cc00aac679e98559391f37ea,2503ae2ae65d364fbcd917882e97f1f4efaccf2d..0d59098f087613d11ef37cdd02c50894eb67e9e1
@@@ -295,9 -295,6 +295,9 @@@ static void krealloc_more_oob_helper(st
        ptr2 = krealloc(ptr1, size2, GFP_KERNEL);
        KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr2);
  
 +      /* Suppress -Warray-bounds warnings. */
 +      OPTIMIZER_HIDE_VAR(ptr2);
 +
        /* All offsets up to size2 must be accessible. */
        ptr2[size1 - 1] = 'x';
        ptr2[size1] = 'x';
@@@ -330,9 -327,6 +330,9 @@@ static void krealloc_less_oob_helper(st
        ptr2 = krealloc(ptr1, size2, GFP_KERNEL);
        KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr2);
  
 +      /* Suppress -Warray-bounds warnings. */
 +      OPTIMIZER_HIDE_VAR(ptr2);
 +
        /* Must be accessible for all modes. */
        ptr2[size2 - 1] = 'x';
  
@@@ -546,14 -540,13 +546,14 @@@ static void kmalloc_memmove_invalid_siz
  {
        char *ptr;
        size_t size = 64;
 -      volatile size_t invalid_size = size;
 +      size_t invalid_size = size;
  
        ptr = kmalloc(size, GFP_KERNEL);
        KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
  
        memset((char *)ptr, 0, 64);
        OPTIMIZER_HIDE_VAR(ptr);
 +      OPTIMIZER_HIDE_VAR(invalid_size);
        KUNIT_EXPECT_KASAN_FAIL(test,
                memmove((char *)ptr, (char *)ptr + 4, invalid_size));
        kfree(ptr);
@@@ -1299,7 -1292,7 +1299,7 @@@ static void match_all_not_assigned(stru
        KASAN_TEST_NEEDS_CONFIG_OFF(test, CONFIG_KASAN_GENERIC);
  
        for (i = 0; i < 256; i++) {
-               size = (get_random_int() % 1024) + 1;
+               size = prandom_u32_max(1024) + 1;
                ptr = kmalloc(size, GFP_KERNEL);
                KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
                KUNIT_EXPECT_GE(test, (u8)get_tag(ptr), (u8)KASAN_TAG_MIN);
        }
  
        for (i = 0; i < 256; i++) {
-               order = (get_random_int() % 4) + 1;
+               order = prandom_u32_max(4) + 1;
                pages = alloc_pages(GFP_KERNEL, order);
                ptr = page_address(pages);
                KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
                return;
  
        for (i = 0; i < 256; i++) {
-               size = (get_random_int() % 1024) + 1;
+               size = prandom_u32_max(1024) + 1;
                ptr = vmalloc(size);
                KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ptr);
                KUNIT_EXPECT_GE(test, (u8)get_tag(ptr), (u8)KASAN_TAG_MIN);
diff --combined mm/slab.c
index d1f6e2c64c2ec4a9f328dd4b60e3412726c4a496,60cd19b9ee047d921774ef0bea14fbb0e3afadfa..59c8e28f7b6ab7498ba13a244168f3e021f21155
+++ b/mm/slab.c
@@@ -1619,7 -1619,7 +1619,7 @@@ static void slab_destroy(struct kmem_ca
         * although actual page can be freed in rcu context
         */
        if (OFF_SLAB(cachep))
 -              kmem_cache_free(cachep->freelist_cache, freelist);
 +              kfree(freelist);
  }
  
  /*
@@@ -1671,27 -1671,21 +1671,27 @@@ static size_t calculate_slab_order(stru
                if (flags & CFLGS_OFF_SLAB) {
                        struct kmem_cache *freelist_cache;
                        size_t freelist_size;
 +                      size_t freelist_cache_size;
  
                        freelist_size = num * sizeof(freelist_idx_t);
 -                      freelist_cache = kmalloc_slab(freelist_size, 0u);
 -                      if (!freelist_cache)
 -                              continue;
 -
 -                      /*
 -                       * Needed to avoid possible looping condition
 -                       * in cache_grow_begin()
 -                       */
 -                      if (OFF_SLAB(freelist_cache))
 -                              continue;
 +                      if (freelist_size > KMALLOC_MAX_CACHE_SIZE) {
 +                              freelist_cache_size = PAGE_SIZE << get_order(freelist_size);
 +                      } else {
 +                              freelist_cache = kmalloc_slab(freelist_size, 0u);
 +                              if (!freelist_cache)
 +                                      continue;
 +                              freelist_cache_size = freelist_cache->size;
 +
 +                              /*
 +                               * Needed to avoid possible looping condition
 +                               * in cache_grow_begin()
 +                               */
 +                              if (OFF_SLAB(freelist_cache))
 +                                      continue;
 +                      }
  
                        /* check if off slab has enough benefit */
 -                      if (freelist_cache->size > cachep->size / 2)
 +                      if (freelist_cache_size > cachep->size / 2)
                                continue;
                }
  
@@@ -2067,6 -2061,11 +2067,6 @@@ done
                cachep->flags &= ~(SLAB_RED_ZONE | SLAB_STORE_USER);
  #endif
  
 -      if (OFF_SLAB(cachep)) {
 -              cachep->freelist_cache =
 -                      kmalloc_slab(cachep->freelist_size, 0u);
 -      }
 -
        err = setup_cpu_cache(cachep, gfp);
        if (err) {
                __kmem_cache_release(cachep);
@@@ -2293,7 -2292,7 +2293,7 @@@ static void *alloc_slabmgmt(struct kmem
                freelist = NULL;
        else if (OFF_SLAB(cachep)) {
                /* Slab management obj is off-slab. */
 -              freelist = kmem_cache_alloc_node(cachep->freelist_cache,
 +              freelist = kmalloc_node(cachep->freelist_size,
                                              local_flags, nodeid);
        } else {
                /* We will use last bytes at the slab for freelist */
@@@ -2381,7 -2380,7 +2381,7 @@@ static bool freelist_state_initialize(u
        unsigned int rand;
  
        /* Use best entropy available to define a random shift */
-       rand = get_random_int();
+       rand = get_random_u32();
  
        /* Use a random state if the pre-computed list is not available */
        if (!cachep->random_seq) {
diff --combined net/ipv4/tcp_cdg.c
index 112f28f9369349a54ac719af3de353577a830cf1,efcd145f06db19db49b52b7546154fbe1da76712..ba4d98e510e05790c15e0f572119b54179e76819
@@@ -243,7 -243,7 +243,7 @@@ static bool tcp_cdg_backoff(struct soc
        struct cdg *ca = inet_csk_ca(sk);
        struct tcp_sock *tp = tcp_sk(sk);
  
-       if (prandom_u32() <= nexp_u32(grad * backoff_factor))
+       if (get_random_u32() <= nexp_u32(grad * backoff_factor))
                return false;
  
        if (use_ineff) {
@@@ -375,7 -375,6 +375,7 @@@ static void tcp_cdg_init(struct sock *s
        struct cdg *ca = inet_csk_ca(sk);
        struct tcp_sock *tp = tcp_sk(sk);
  
 +      ca->gradients = NULL;
        /* We silently fall back to window = 1 if allocation fails. */
        if (window > 1)
                ca->gradients = kcalloc(window, sizeof(ca->gradients[0]),
@@@ -389,7 -388,6 +389,7 @@@ static void tcp_cdg_release(struct soc
        struct cdg *ca = inet_csk_ca(sk);
  
        kfree(ca->gradients);
 +      ca->gradients = NULL;
  }
  
  static struct tcp_congestion_ops tcp_cdg __read_mostly = {
diff --combined net/ipv4/udp.c
index 8126f67d18b3410fa1af7ea738ff2f8b9d7826e1,9f2688246deeb87a9e67df0381d101031ee97314..662d717d512335bcb99f57b829402f61efebbe94
@@@ -246,7 -246,7 +246,7 @@@ int udp_lib_get_port(struct sock *sk, u
                inet_get_local_port_range(net, &low, &high);
                remaining = (high - low) + 1;
  
-               rand = prandom_u32();
+               rand = get_random_u32();
                first = reciprocal_scale(rand, remaining) + low;
                /*
                 * force rand to be an odd multiple of UDP_HTABLE_SIZE
@@@ -1598,7 -1598,7 +1598,7 @@@ drop
  }
  EXPORT_SYMBOL_GPL(__udp_enqueue_schedule_skb);
  
 -void udp_destruct_sock(struct sock *sk)
 +void udp_destruct_common(struct sock *sk)
  {
        /* reclaim completely the forward allocated memory */
        struct udp_sock *up = udp_sk(sk);
                kfree_skb(skb);
        }
        udp_rmem_release(sk, total, 0, true);
 +}
 +EXPORT_SYMBOL_GPL(udp_destruct_common);
  
 +static void udp_destruct_sock(struct sock *sk)
 +{
 +      udp_destruct_common(sk);
        inet_sock_destruct(sk);
  }
 -EXPORT_SYMBOL_GPL(udp_destruct_sock);
  
  int udp_init_sock(struct sock *sk)
  {
        sk->sk_destruct = udp_destruct_sock;
        return 0;
  }
 -EXPORT_SYMBOL_GPL(udp_init_sock);
  
  void skb_consume_udp(struct sock *sk, struct sk_buff *skb, int len)
  {
diff --combined net/sunrpc/xprt.c
index 71dc2637344416d560b036e40f7acc54a2fffd4f,9407007f47aee35b23dbb65b29373a7cffdc92ee..656cec2083718580f9060e9a370e88b95e5c4b4d
@@@ -1788,7 -1788,7 +1788,7 @@@ static int xprt_alloc_id(struct rpc_xpr
  {
        int id;
  
 -      id = ida_simple_get(&rpc_xprt_ids, 0, 0, GFP_KERNEL);
 +      id = ida_alloc(&rpc_xprt_ids, GFP_KERNEL);
        if (id < 0)
                return id;
  
  
  static void xprt_free_id(struct rpc_xprt *xprt)
  {
 -      ida_simple_remove(&rpc_xprt_ids, xprt->id);
 +      ida_free(&rpc_xprt_ids, xprt->id);
  }
  
  struct rpc_xprt *xprt_alloc(struct net *net, size_t size,
                        goto out_free;
                list_add(&req->rq_list, &xprt->free);
        }
 -      if (max_alloc > num_prealloc)
 -              xprt->max_reqs = max_alloc;
 -      else
 -              xprt->max_reqs = num_prealloc;
 +      xprt->max_reqs = max_t(unsigned int, max_alloc, num_prealloc);
        xprt->min_reqs = num_prealloc;
        xprt->num_reqs = num_prealloc;
  
@@@ -1865,7 -1868,7 +1865,7 @@@ xprt_alloc_xid(struct rpc_xprt *xprt
  static void
  xprt_init_xid(struct rpc_xprt *xprt)
  {
-       xprt->xid = prandom_u32();
+       xprt->xid = get_random_u32();
  }
  
  static void
diff --combined net/sunrpc/xprtsock.c
index f34d5427b66ce578a60c32acd2a784bfd662ba9a,f55ff5155b6e28bb54b55335b3b77b94366c545d..915b9902f673b2ace31daaf86ce532bc0b6523f1
@@@ -261,7 -261,7 +261,7 @@@ static void xs_format_common_peer_addre
        switch (sap->sa_family) {
        case AF_LOCAL:
                sun = xs_addr_un(xprt);
 -              strlcpy(buf, sun->sun_path, sizeof(buf));
 +              strscpy(buf, sun->sun_path, sizeof(buf));
                xprt->address_strings[RPC_DISPLAY_ADDR] =
                                                kstrdup(buf, GFP_KERNEL);
                break;
@@@ -1619,7 -1619,7 +1619,7 @@@ static int xs_get_random_port(void
        if (max < min)
                return -EADDRINUSE;
        range = max - min + 1;
-       rand = (unsigned short) prandom_u32() % range;
+       rand = prandom_u32_max(range);
        return rand + min;
  }
  
@@@ -1978,7 -1978,8 +1978,7 @@@ static void xs_local_connect(struct rpc
                 * we'll need to figure out how to pass a namespace to
                 * connect.
                 */
 -              task->tk_rpc_status = -ENOTCONN;
 -              rpc_exit(task, -ENOTCONN);
 +              rpc_task_set_rpc_status(task, -ENOTCONN);
                goto out_wake;
        }
        ret = xs_local_setup_socket(transport);