Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 09a81269 authored by Jarkko Lavinen's avatar Jarkko Lavinen Committed by Linus Torvalds
Browse files

i82875p_edac: fix module remove



Fix module removal bugs of i82875p_edac.  Also i82975x_edac code seems to
have the same module removal bugs as in i82875p_edac.

The problems were:

1. In module removal i82875p_remove_one() is never called.

   Variable i82875p_registered is newer changed from 1, which
   guarantees i82875p_remove_one() is not called (and even if it were
   called, it would be called in wrong order).

   As a result, the edac_mc workque is not stopped and keeps probing.
   If kernel debugging options are not enabled, user may not notice
   anything going wrong.

   if debugging options are enabled and I do "rmmod i82875p_edac", I
   get:

      edac debug: edac_pci_workq_function() checking
      BUG: unable to handle kernel paging request at f882d16f
      ...
      call trace:
       [<f8834df3>] ? edac_mc_workq_function+0x55/0x7e [edac_core]
       [<c0233974>] ? run_workqueue+0xd7/0x1a5
       [<c023392f>] ? run_workqueue+0x92/0x1a5
       [<f8834d9e>] ? edac_mc_workq_function+0x0/0x7e [edac_core]
       [<c0233af9>] ? worker_thread+0xb7/0xc3
       [<c0236a7b>] ? autoremove_wake_function+0x0/0x33
       [<c0233a42>] ? worker_thread+0x0/0xc3
       [<c0236809>] ? kthread+0x3b/0x61
       [<c02367ce>] ? kthread+0x0/0x61
       [<c0204587>] ? kernel_thread_helper+0x7/0x10

   Fix for this is to get rid of needles variable i82875p_registered
   altogether and run i82875p_remove_one() *before*
   pci_unregister_driver().

2. edac_mc_del_mc() uses mci after freeing mci

   edac_mc_del_mc() calls calls edac_remove_sysfs_mci_device().  The
   kobject refcount of mci drops to 0 and mci is freed.  After this
   mci is accessed via debug print and i82875p_remove_one() still
   uses mci->pvt and tries to free mci again with edac_mc_free().

   The fix for this is add kobject_get(&mci->edac_mci_kobj) after
   edac_mc_alloc(). Then the mci is still available after returning
   from edac_mc_del_mc() with refcount 1, and mci->pvt is still
   available. When i82875p_remove_one() finally calls edac_mc_free(),
   this will cause kobject_put() and mci is released properly.

Signed-off-by: default avatarJarkko Lavinen <jlavi@iki.fi>
Cc: Doug Thompson <norsk5@yahoo.com>
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 307d1144
Loading
Loading
Loading
Loading
+7 −6
Original line number Diff line number Diff line
@@ -182,8 +182,6 @@ static struct pci_dev *mci_pdev; /* init dev: in case that AGP code has
					 * already registered driver
					 */

static int i82875p_registered = 1;

static struct edac_pci_ctl_info *i82875p_pci;

static void i82875p_get_error_info(struct mem_ctl_info *mci,
@@ -410,6 +408,9 @@ static int i82875p_probe1(struct pci_dev *pdev, int dev_idx)
		goto fail0;
	}

	/* Keeps mci available after edac_mc_del_mc() till edac_mc_free() */
	kobject_get(&mci->edac_mci_kobj);

	debugf3("%s(): init mci\n", __func__);
	mci->dev = &pdev->dev;
	mci->mtype_cap = MEM_FLAG_DDR;
@@ -452,6 +453,7 @@ static int i82875p_probe1(struct pci_dev *pdev, int dev_idx)
	return 0;

fail1:
	kobject_put(&mci->edac_mci_kobj);
	edac_mc_free(mci);

fail0:
@@ -579,12 +581,11 @@ static void __exit i82875p_exit(void)
{
	debugf3("%s()\n", __func__);

	pci_unregister_driver(&i82875p_driver);

	if (!i82875p_registered) {
	i82875p_remove_one(mci_pdev);
	pci_dev_put(mci_pdev);
	}

	pci_unregister_driver(&i82875p_driver);

}

module_init(i82875p_init);