Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 359977
b: refs/heads/master
c: 80cc7d8
h: refs/heads/master
i:
  359975: ad34af1
v: v3
  • Loading branch information
Mauro Carvalho Chehab committed Feb 21, 2013
1 parent a258194 commit fd95e61
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 5 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: c2c93dbc97622e26dc19edc71e50ebaa996d7804
refs/heads/master: 80cc7d87d5eb34375f916d282450a0906a8ead60
25 changes: 21 additions & 4 deletions trunk/drivers/edac/edac_mc.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,12 @@
static DEFINE_MUTEX(mem_ctls_mutex);
static LIST_HEAD(mc_devices);

/*
* Used to lock EDAC MC to just one module, avoiding two drivers e. g.
* apei/ghes and i7core_edac to be used at the same time.
*/
static void const *edac_mc_owner;

unsigned edac_dimm_info_location(struct dimm_info *dimm, char *buf,
unsigned len)
{
Expand Down Expand Up @@ -659,16 +665,18 @@ static int add_mc_to_global_list(struct mem_ctl_info *mci)
return 1;
}

static void del_mc_from_global_list(struct mem_ctl_info *mci)
static int del_mc_from_global_list(struct mem_ctl_info *mci)
{
atomic_dec(&edac_handlers);
int handlers = atomic_dec_return(&edac_handlers);
list_del_rcu(&mci->link);

/* these are for safe removal of devices from global list while
* NMI handlers may be traversing list
*/
synchronize_rcu();
INIT_LIST_HEAD(&mci->link);

return handlers;
}

/**
Expand Down Expand Up @@ -712,6 +720,7 @@ EXPORT_SYMBOL(edac_mc_find);
/* FIXME - should a warning be printed if no error detection? correction? */
int edac_mc_add_mc(struct mem_ctl_info *mci)
{
int ret = -EINVAL;
edac_dbg(0, "\n");

#ifdef CONFIG_EDAC_DEBUG
Expand Down Expand Up @@ -742,6 +751,11 @@ int edac_mc_add_mc(struct mem_ctl_info *mci)
#endif
mutex_lock(&mem_ctls_mutex);

if (edac_mc_owner && edac_mc_owner != mci->mod_name) {
ret = -EPERM;
goto fail0;
}

if (add_mc_to_global_list(mci))
goto fail0;

Expand All @@ -768,6 +782,8 @@ int edac_mc_add_mc(struct mem_ctl_info *mci)
edac_mc_printk(mci, KERN_INFO, "Giving out device to '%s' '%s':"
" DEV %s\n", mci->mod_name, mci->ctl_name, edac_dev_name(mci));

edac_mc_owner = mci->mod_name;

mutex_unlock(&mem_ctls_mutex);
return 0;

Expand All @@ -776,7 +792,7 @@ int edac_mc_add_mc(struct mem_ctl_info *mci)

fail0:
mutex_unlock(&mem_ctls_mutex);
return 1;
return ret;
}
EXPORT_SYMBOL_GPL(edac_mc_add_mc);

Expand All @@ -802,7 +818,8 @@ struct mem_ctl_info *edac_mc_del_mc(struct device *dev)
return NULL;
}

del_mc_from_global_list(mci);
if (!del_mc_from_global_list(mci))
edac_mc_owner = NULL;
mutex_unlock(&mem_ctls_mutex);

/* flush workq processes */
Expand Down

0 comments on commit fd95e61

Please sign in to comment.