title: I am incorrectly using a list in a kernel module, and I'm not sure where I am going wrong
body: <p>I am more or less a Linux kernel noob, and I am writing a toy kernel module that has a function that gets all of the processes that currently have more than 3 open file descriptors. I am trying to avoid allocating memory while holding the <strong>rcu_read_lock</strong>, so I want to pre-allocate the most nodes I would likely need into a temporary list, and then transfer them to the main list that was passed in as I need them.</p>
  <p>The problem definitely is occurring at the end of the function where I am doing something wrong with the <strong>list_for_each_entry</strong>. The dmesg output definitely shows that there is something going wrong in this part of the function. I am not sure if the problem lies in my cleanup there, or if something I am doing wrong prior to this is causing my issue. The function is below:</p>
  <pre><code>static int refresh_proc_list(struct list_head *head)
  {
      LIST_HEAD(tmp_list);
      struct task_struct *task_list;
      int ret = 0;
      size_t procs = 0;
      int fds = 0;
      struct proc_info *proc = NULL;
      struct proc_info *pos = NULL;
  
      if (NULL == head)
      {
          pr_warn(&quot;refresh_proc_list: invalid argument\n&quot;);
          ret = -EFAULT;
          goto exit_refresh_proc_list; 
      }
      
      // Get proc count
      rcu_read_lock();
      for_each_process(task_list)
      {
          procs++;
      }
      rcu_read_unlock();
      pr_info(&quot;refresh_proc_list: allocating nodes for %ld processes\n&quot;, procs);
  
      // Alloc proc count number of nodes and add them to the temp list
      for (; procs != 0; procs--)
      {
          proc = kzalloc(sizeof(struct proc_info), GFP_KERNEL);
          if (NULL == proc)
          {
              pr_warn(&quot;refresh_proc_list: allocation failed\n&quot;);
              ret = -ENOMEM;
              goto exit_refresh_proc_list;
          }
          list_add(&amp;proc-&gt;list, &amp;tmp_list);
      }
  
      // Find processes with more than 3 file descriptors open
      rcu_read_lock();
      for_each_process(task_list)
      {
          fds = atomic_read(&amp;(task_list-&gt;files-&gt;count));
  
          // Verify there are nodes left to assign
          if (list_empty(&amp;tmp_list))
          {
              pr_info(&quot;refresh_proc_list: insufficient nodes allocated\n&quot;);
              ret = -ENOMEM;
              goto exit_refresh_proc_list;
          }
          if (3 &lt; fds)
          {
              // Grab temp list head and then assign values
              proc = list_first_entry(&amp;tmp_list, struct proc_info, list);
              if (NULL == proc)
              {
                  pr_warn(&quot;refresh_proc_list: failed to get list first node\n&quot;);
                  ret = -EFAULT;
                  goto exit_refresh_proc_list;
              }
              proc-&gt;pid = task_list-&gt;pid;
              memcpy(task_list-&gt;comm, proc-&gt;comm, TASK_COMM_LEN);
              proc-&gt;fds = fds;
              // Move proc from tmp_list to proc_list
              list_move(&amp;tmp_list, head);
              procs++;
          }
      }
      rcu_read_unlock();
      pr_info(&quot;refresh_proc_list: added %lu processes to list\n&quot;, procs);
  
  exit_refresh_proc_list:
      // Free any temp nodes that weren't used
      pr_info(&quot;refresh_proc_list: cleaning up\n&quot;);
      list_for_each_entry(pos, &amp;tmp_list, list)
      {
          list_del(&amp;pos-&gt;list);
          kfree(pos);
          pos = NULL;
          procs--;
      }
      pr_info(&quot;refresh_proc_list: I SHOULD SAY '0' here -&gt; %ld\n&quot;, procs);
  
      pr_info(&quot;refresh_proc_list: %d\n&quot;, ret);
      return ret;
  }
  </code></pre>
  <p>The dmesg output that comes when I run this module is pasted below. I've been grinding on this issue for a while now. Any help would be appreciated.</p>
  <pre><code>[29096.539540] seq_open: attempting to open
  [29096.539547] seq_start: attempting to start read
  [29096.539582] refresh_proc_list: allocating nodes for 240 processes
  [29096.539611] refresh_proc_list: added 162 processes to list
  [29096.539611] refresh_proc_list: cleaning up
  [29096.539615] BUG: unable to handle page fault for address: fffff0c3ec0960c8
  [29096.539617] #PF: supervisor read access in kernel mode
  [29096.539618] #PF: error_code(0x0000) - not-present page
  [29096.539618] PGD 223fcb067 P4D 223fcb067 PUD 0 
  [29096.539620] Oops: 0000 [#1] SMP NOPTI
  [29096.539621] CPU: 3 PID: 50441 Comm: cat Tainted: G        W  OE     5.8.0-43-generic #49~20.04.1-Ubuntu
  [29096.539622] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
  [29096.539625] RIP: 0010:kfree+0x55/0x250
  [29096.539626] Code: 80 49 01 dc 0f 82 03 02 00 00 48 c7 c0 00 00 00 80 48 2b 05 55 16 1d 01 49 01 c4 49 c1 ec 0c 49 c1 e4 06 4c 03 25 33 16 1d 01 &lt;49&gt; 8b 44 24 08 48 8d 50 ff a8 01 4c 0f 45 e2 49 8b 54 24 08 48 8d
  [29096.539627] RSP: 0018:ffffa57242583d90 EFLAGS: 00010286
  [29096.539628] RAX: 0000682840000000 RBX: ffffa57242583db0 RCX: dead000000000100
  [29096.539628] RDX: ffffa57242583dd8 RSI: 0000000000000086 RDI: ffffa57242583db0
  [29096.539628] RBP: ffffa57242583db0 R08: ffff97d95bb98cd0 R09: 0000000000000004
  [29096.539629] R10: 0000000000000000 R11: 0000000000000001 R12: fffff0c3ec0960c0
  [29096.539629] R13: ffffffffc070a34e R14: 0000000000000000 R15: dead000000000122
  [29096.539630] FS:  00007f5a6ed05580(0000) GS:ffff97d95bb80000(0000) knlGS:0000000000000000
  [29096.539630] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
  [29096.539631] CR2: fffff0c3ec0960c8 CR3: 00000001ad12e000 CR4: 00000000000006e0
  [29096.539632] Call Trace:
  [29096.539636]  ct_seq_start+0x204/0x281 [proc_entry]
  [29096.539639]  seq_read+0x93/0x400
  [29096.539641]  proc_reg_read+0x66/0x90
  [29096.539642]  vfs_read+0xaa/0x190
  [29096.539643]  ksys_read+0x67/0xe0
  [29096.539644]  __x64_sys_read+0x1a/0x20
  [29096.539646]  do_syscall_64+0x49/0xc0
  [29096.539648]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
  [29096.539648] RIP: 0033:0x7f5a6ec23142
  [29096.539649] Code: c0 e9 c2 fe ff ff 50 48 8d 3d 3a ca 0a 00 e8 f5 19 02 00 0f 1f 44 00 00 f3 0f 1e fa 64 8b 04 25 18 00 00 00 85 c0 75 10 0f 05 &lt;48&gt; 3d 00 f0 ff ff 77 56 c3 0f 1f 44 00 00 48 83 ec 28 48 89 54 24
  [29096.539650] RSP: 002b:00007ffed8266da8 EFLAGS: 00000246 ORIG_RAX: 0000000000000000
  [29096.539650] RAX: ffffffffffffffda RBX: 0000000000020000 RCX: 00007f5a6ec23142
  [29096.539651] RDX: 0000000000020000 RSI: 00007f5a6dd13000 RDI: 0000000000000003
  [29096.539651] RBP: 00007f5a6dd13000 R08: 00007f5a6dd12010 R09: 0000000000000000
  [29096.539652] R10: 0000000000000022 R11: 0000000000000246 R12: 000056043824b1f0
  [29096.539652] R13: 0000000000000003 R14: 0000000000020000 R15: 0000000000020000
  [29096.539653] Modules linked in: proc_entry(OE) btrfs blake2b_generic xor raid6_pq ufs qnx4 hfsplus hfs minix ntfs msdos jfs xfs libcrc32c cpuid nls_utf8 isofs vboxvideo(OE) binfmt_misc nls_iso8859_1 snd_intel8x0 snd_ac97_codec ac97_bus snd_pcm snd_seq_midi snd_seq_midi_event snd_rawmidi snd_seq snd_seq_device snd_timer joydev input_leds serio_raw snd vboxguest(OE) soundcore mac_hid sch_fq_codel vmwgfx ttm drm_kms_helper cec rc_core fb_sys_fops syscopyarea sysfillrect sysimgblt msr parport_pc ppdev lp parport drm ip_tables x_tables autofs4 hid_generic usbhid hid psmouse ahci libahci pata_acpi lpc_ich i2c_piix4 e1000 video [last unloaded: procfds]
  [29096.539689] CR2: fffff0c3ec0960c8
  [29096.539690] ---[ end trace 48dcbb7c0361fa85 ]---
  [29096.539692] RIP: 0010:kfree+0x55/0x250
  [29096.539692] Code: 80 49 01 dc 0f 82 03 02 00 00 48 c7 c0 00 00 00 80 48 2b 05 55 16 1d 01 49 01 c4 49 c1 ec 0c 49 c1 e4 06 4c 03 25 33 16 1d 01 &lt;49&gt; 8b 44 24 08 48 8d 50 ff a8 01 4c 0f 45 e2 49 8b 54 24 08 48 8d
  [29096.539693] RSP: 0018:ffffa57242583d90 EFLAGS: 00010286
  [29096.539693] RAX: 0000682840000000 RBX: ffffa57242583db0 RCX: dead000000000100
  [29096.539694] RDX: ffffa57242583dd8 RSI: 0000000000000086 RDI: ffffa57242583db0
  [29096.539694] RBP: ffffa57242583db0 R08: ffff97d95bb98cd0 R09: 0000000000000004
  [29096.539695] R10: 0000000000000000 R11: 0000000000000001 R12: fffff0c3ec0960c0
  [29096.539695] R13: ffffffffc070a34e R14: 0000000000000000 R15: dead000000000122
  [29096.539696] FS:  00007f5a6ed05580(0000) GS:ffff97d95bb80000(0000) knlGS:0000000000000000
  [29096.539696] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
  [29096.539697] CR2: fffff0c3ec0960c8 CR3: 00000001ad12e000 CR4: 00000000000006e0```
  </code></pre>