Skip to content

Commit

Permalink
Merge tag 'driver-core-3.15-rc2' of git://git.kernel.org/pub/scm/linu…
Browse files Browse the repository at this point in the history
…x/kernel/git/gregkh/driver-core

Pull driver core fixes from Greg KH:
 "Here are some driver core fixes for 3.15-rc2.  Also in here are some
  documentation updates, as well as an API removal that had to wait for
  after -rc1 due to the cleanups coming into you from multiple developer
  trees (this one and the PPC tree.)

  All have been in linux next successfully"

* tag 'driver-core-3.15-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/driver-core:
  drivers/base/dd.c incorrect pr_debug() parameters
  Documentation: Update stable address in Chinese and Japanese translations
  topology: Fix compilation warning when not in SMP
  Chinese: add translation of io_ordering.txt
  stable_kernel_rules: spelling/word usage
  sysfs, driver-core: remove unused {sysfs|device}_schedule_callback_owner()
  kernfs: protect lazy kernfs_iattrs allocation with mutex
  fs: Don't return 0 from get_anon_bdev
  • Loading branch information
torvalds committed Apr 18, 2014
2 parents 8cb652b + 94f8cc0 commit 60fbf2b
Show file tree
Hide file tree
Showing 14 changed files with 92 additions and 160 deletions.
2 changes: 1 addition & 1 deletion Documentation/ja_JP/HOWTO
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ Andrew Morton が Linux-kernel メーリングリストにカーネルリリー
もし、3.x.y カーネルが存在しない場合には、番号が一番大きい 3.x が
最新の安定版カーネルです。

3.x.y は "stable" チーム <[email protected]> でメンテされており、必
3.x.y は "stable" チーム <stable@vger.kernel.org> でメンテされており、必
要に応じてリリースされます。通常のリリース期間は 2週間毎ですが、差し迫っ
た問題がなければもう少し長くなることもあります。セキュリティ関連の問題
の場合はこれに対してだいたいの場合、すぐにリリースがされます。
Expand Down
6 changes: 3 additions & 3 deletions Documentation/ja_JP/stable_kernel_rules.txt
Original file line number Diff line number Diff line change
Expand Up @@ -50,16 +50,16 @@ linux-2.6.29/Documentation/stable_kernel_rules.txt

-stable ツリーにパッチを送付する手続き-

- 上記の規則に従っているかを確認した後に、[email protected] にパッチ
- 上記の規則に従っているかを確認した後に、stable@vger.kernel.org にパッチ
を送る。
- 送信者はパッチがキューに受け付けられた際には ACK を、却下された場合
には NAK を受け取る。この反応は開発者たちのスケジュールによって、数
日かかる場合がある。
- もし受け取られたら、パッチは他の開発者たちと関連するサブシステムの
メンテナーによるレビューのために -stable キューに追加される。
- パッチに [email protected] のアドレスが付加されているときには、それ
- パッチに stable@vger.kernel.org のアドレスが付加されているときには、それ
が Linus のツリーに入る時に自動的に stable チームに email される。
- セキュリティパッチはこのエイリアス ([email protected]) に送られるべ
- セキュリティパッチはこのエイリアス (stable@vger.kernel.org) に送られるべ
きではなく、代わりに [email protected] のアドレスに送られる。

レビューサイクル-
Expand Down
2 changes: 1 addition & 1 deletion Documentation/stable_kernel_rules.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ Procedure for submitting patches to the -stable tree:
the stable tree without anything else needing to be done by the author
or subsystem maintainer.
- If the patch requires other patches as prerequisites which can be
cherry-picked than this can be specified in the following format in
cherry-picked, then this can be specified in the following format in
the sign-off area:

Cc: <[email protected]> # 3.3.x: a1f84a3: sched: Check for idle
Expand Down
2 changes: 1 addition & 1 deletion Documentation/zh_CN/HOWTO
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ kernel.org网站的pub/linux/kernel/v2.6/目录下找到它。它的开发遵循
如果没有2.6.x.y版本内核存在,那么最新的2.6.x版本内核就相当于是当前的稳定
版内核。

2.6.x.y版本由“稳定版”小组(邮件地址<[email protected]>)维护,一般隔周发
2.6.x.y版本由“稳定版”小组(邮件地址<stable@vger.kernel.org>)维护,一般隔周发
布新版本。

内核源码中的Documentation/stable_kernel_rules.txt文件具体描述了可被稳定
Expand Down
67 changes: 67 additions & 0 deletions Documentation/zh_CN/io_ordering.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
Chinese translated version of Documentation/io_orderings.txt

If you have any comment or update to the content, please contact the
original document maintainer directly. However, if you have a problem
communicating in English you can also ask the Chinese maintainer for
help. Contact the Chinese maintainer if this translation is outdated
or if there is a problem with the translation.

Chinese maintainer: Lin Yongting <[email protected]>
---------------------------------------------------------------------
Documentation/io_ordering.txt 的中文翻译

如果想评论或更新本文的内容,请直接联系原文档的维护者。如果你使用英文
交流有困难的话,也可以向中文版维护者求助。如果本翻译更新不及时或者翻
译存在问题,请联系中文版维护者。

中文版维护者: 林永听 Lin Yongting <[email protected]>
中文版翻译者: 林永听 Lin Yongting <[email protected]>
中文版校译者: 林永听 Lin Yongting <[email protected]>


以下为正文
---------------------------------------------------------------------

在某些平台上,所谓的内存映射I/O是弱顺序。在这些平台上,驱动开发者有责任
保证I/O内存映射地址的写操作按程序图意的顺序达到设备。通常读取一个“安全”
设备寄存器或桥寄存器,触发IO芯片清刷未处理的写操作到达设备后才处理读操作,
而达到保证目的。驱动程序通常在spinlock保护的临界区退出之前使用这种技术。
这也可以保证后面的写操作只在前面的写操作之后到达设备(这非常类似于内存
屏障操作,mb(),不过仅适用于I/O)。

假设一个设备驱动程的具体例子:

...
CPU A: spin_lock_irqsave(&dev_lock, flags)
CPU A: val = readl(my_status);
CPU A: ...
CPU A: writel(newval, ring_ptr);
CPU A: spin_unlock_irqrestore(&dev_lock, flags)
...
CPU B: spin_lock_irqsave(&dev_lock, flags)
CPU B: val = readl(my_status);
CPU B: ...
CPU B: writel(newval2, ring_ptr);
CPU B: spin_unlock_irqrestore(&dev_lock, flags)
...

上述例子中,设备可能会先接收到newval2的值,然后接收到newval的值,问题就
发生了。不过很容易通过下面方法来修复:

...
CPU A: spin_lock_irqsave(&dev_lock, flags)
CPU A: val = readl(my_status);
CPU A: ...
CPU A: writel(newval, ring_ptr);
CPU A: (void)readl(safe_register); /* 配置寄存器?*/
CPU A: spin_unlock_irqrestore(&dev_lock, flags)
...
CPU B: spin_lock_irqsave(&dev_lock, flags)
CPU B: val = readl(my_status);
CPU B: ...
CPU B: writel(newval2, ring_ptr);
CPU B: (void)readl(safe_register); /* 配置寄存器?*/
CPU B: spin_unlock_irqrestore(&dev_lock, flags)

在解决方案中,读取safe_register寄存器,触发IO芯片清刷未处理的写操作,
再处理后面的读操作,防止引发数据不一致问题。
2 changes: 1 addition & 1 deletion Documentation/zh_CN/stable_kernel_rules.txt
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ Documentation/stable_kernel_rules.txt 的中文翻译

向稳定版代码树提交补丁的过程:

- 在确认了补丁符合以上的规则后,将补丁发送到[email protected]
- 在确认了补丁符合以上的规则后,将补丁发送到stable@vger.kernel.org。
- 如果补丁被接受到队列里,发送者会收到一个ACK回复,如果没有被接受,收
到的是NAK回复。回复需要几天的时间,这取决于开发者的时间安排。
- 被接受的补丁会被加到稳定版本队列里,等待其他开发者的审查。
Expand Down
33 changes: 0 additions & 33 deletions drivers/base/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -614,39 +614,6 @@ void device_remove_bin_file(struct device *dev,
}
EXPORT_SYMBOL_GPL(device_remove_bin_file);

/**
* device_schedule_callback_owner - helper to schedule a callback for a device
* @dev: device.
* @func: callback function to invoke later.
* @owner: module owning the callback routine
*
* Attribute methods must not unregister themselves or their parent device
* (which would amount to the same thing). Attempts to do so will deadlock,
* since unregistration is mutually exclusive with driver callbacks.
*
* Instead methods can call this routine, which will attempt to allocate
* and schedule a workqueue request to call back @func with @dev as its
* argument in the workqueue's process context. @dev will be pinned until
* @func returns.
*
* This routine is usually called via the inline device_schedule_callback(),
* which automatically sets @owner to THIS_MODULE.
*
* Returns 0 if the request was submitted, -ENOMEM if storage could not
* be allocated, -ENODEV if a reference to @owner isn't available.
*
* NOTE: This routine won't work if CONFIG_SYSFS isn't set! It uses an
* underlying sysfs routine (since it is intended for use by attribute
* methods), and if sysfs isn't available you'll get nothing but -ENOSYS.
*/
int device_schedule_callback_owner(struct device *dev,
void (*func)(struct device *), struct module *owner)
{
return sysfs_schedule_callback(&dev->kobj,
(void (*)(void *)) func, dev, owner);
}
EXPORT_SYMBOL_GPL(device_schedule_callback_owner);

static void klist_children_get(struct klist_node *n)
{
struct device_private *p = to_device_private_parent(n);
Expand Down
4 changes: 2 additions & 2 deletions drivers/base/dd.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,8 +187,8 @@ static void driver_bound(struct device *dev)
return;
}

pr_debug("driver: '%s': %s: bound to device '%s'\n", dev_name(dev),
__func__, dev->driver->name);
pr_debug("driver: '%s': %s: bound to device '%s'\n", dev->driver->name,
__func__, dev_name(dev));

klist_add_tail(&dev->p->knode_driver, &dev->driver->p->klist_devices);

Expand Down
3 changes: 1 addition & 2 deletions drivers/base/topology.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,7 @@
static ssize_t show_##name(struct device *dev, \
struct device_attribute *attr, char *buf) \
{ \
unsigned int cpu = dev->id; \
return sprintf(buf, "%d\n", topology_##name(cpu)); \
return sprintf(buf, "%d\n", topology_##name(dev->id)); \
}

#if defined(topology_thread_cpumask) || defined(topology_core_cpumask) || \
Expand Down
14 changes: 10 additions & 4 deletions fs/kernfs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,18 @@ void __init kernfs_inode_init(void)

static struct kernfs_iattrs *kernfs_iattrs(struct kernfs_node *kn)
{
static DEFINE_MUTEX(iattr_mutex);
struct kernfs_iattrs *ret;
struct iattr *iattrs;

mutex_lock(&iattr_mutex);

if (kn->iattr)
return kn->iattr;
goto out_unlock;

kn->iattr = kzalloc(sizeof(struct kernfs_iattrs), GFP_KERNEL);
if (!kn->iattr)
return NULL;
goto out_unlock;
iattrs = &kn->iattr->ia_iattr;

/* assign default attributes */
Expand All @@ -65,8 +69,10 @@ static struct kernfs_iattrs *kernfs_iattrs(struct kernfs_node *kn)
iattrs->ia_atime = iattrs->ia_mtime = iattrs->ia_ctime = CURRENT_TIME;

simple_xattrs_init(&kn->iattr->xattrs);

return kn->iattr;
out_unlock:
ret = kn->iattr;
mutex_unlock(&iattr_mutex);
return ret;
}

static int __kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr)
Expand Down
5 changes: 4 additions & 1 deletion fs/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -800,7 +800,10 @@ void emergency_remount(void)

static DEFINE_IDA(unnamed_dev_ida);
static DEFINE_SPINLOCK(unnamed_dev_lock);/* protects the above */
static int unnamed_dev_start = 0; /* don't bother trying below it */
/* Many userspace utilities consider an FSID of 0 invalid.
* Always return at least 1 from get_anon_bdev.
*/
static int unnamed_dev_start = 1;

int get_anon_bdev(dev_t *p)
{
Expand Down
92 changes: 0 additions & 92 deletions fs/sysfs/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -453,95 +453,3 @@ void sysfs_remove_bin_file(struct kobject *kobj,
kernfs_remove_by_name(kobj->sd, attr->attr.name);
}
EXPORT_SYMBOL_GPL(sysfs_remove_bin_file);

struct sysfs_schedule_callback_struct {
struct list_head workq_list;
struct kobject *kobj;
void (*func)(void *);
void *data;
struct module *owner;
struct work_struct work;
};

static struct workqueue_struct *sysfs_workqueue;
static DEFINE_MUTEX(sysfs_workq_mutex);
static LIST_HEAD(sysfs_workq);
static void sysfs_schedule_callback_work(struct work_struct *work)
{
struct sysfs_schedule_callback_struct *ss = container_of(work,
struct sysfs_schedule_callback_struct, work);

(ss->func)(ss->data);
kobject_put(ss->kobj);
module_put(ss->owner);
mutex_lock(&sysfs_workq_mutex);
list_del(&ss->workq_list);
mutex_unlock(&sysfs_workq_mutex);
kfree(ss);
}

/**
* sysfs_schedule_callback - helper to schedule a callback for a kobject
* @kobj: object we're acting for.
* @func: callback function to invoke later.
* @data: argument to pass to @func.
* @owner: module owning the callback code
*
* sysfs attribute methods must not unregister themselves or their parent
* kobject (which would amount to the same thing). Attempts to do so will
* deadlock, since unregistration is mutually exclusive with driver
* callbacks.
*
* Instead methods can call this routine, which will attempt to allocate
* and schedule a workqueue request to call back @func with @data as its
* argument in the workqueue's process context. @kobj will be pinned
* until @func returns.
*
* Returns 0 if the request was submitted, -ENOMEM if storage could not
* be allocated, -ENODEV if a reference to @owner isn't available,
* -EAGAIN if a callback has already been scheduled for @kobj.
*/
int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *),
void *data, struct module *owner)
{
struct sysfs_schedule_callback_struct *ss, *tmp;

if (!try_module_get(owner))
return -ENODEV;

mutex_lock(&sysfs_workq_mutex);
list_for_each_entry_safe(ss, tmp, &sysfs_workq, workq_list)
if (ss->kobj == kobj) {
module_put(owner);
mutex_unlock(&sysfs_workq_mutex);
return -EAGAIN;
}
mutex_unlock(&sysfs_workq_mutex);

if (sysfs_workqueue == NULL) {
sysfs_workqueue = create_singlethread_workqueue("sysfsd");
if (sysfs_workqueue == NULL) {
module_put(owner);
return -ENOMEM;
}
}

ss = kmalloc(sizeof(*ss), GFP_KERNEL);
if (!ss) {
module_put(owner);
return -ENOMEM;
}
kobject_get(kobj);
ss->kobj = kobj;
ss->func = func;
ss->data = data;
ss->owner = owner;
INIT_WORK(&ss->work, sysfs_schedule_callback_work);
INIT_LIST_HEAD(&ss->workq_list);
mutex_lock(&sysfs_workq_mutex);
list_add_tail(&ss->workq_list, &sysfs_workq);
mutex_unlock(&sysfs_workq_mutex);
queue_work(sysfs_workqueue, &ss->work);
return 0;
}
EXPORT_SYMBOL_GPL(sysfs_schedule_callback);
11 changes: 1 addition & 10 deletions include/linux/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -566,12 +566,6 @@ extern int __must_check device_create_bin_file(struct device *dev,
const struct bin_attribute *attr);
extern void device_remove_bin_file(struct device *dev,
const struct bin_attribute *attr);
extern int device_schedule_callback_owner(struct device *dev,
void (*func)(struct device *dev), struct module *owner);

/* This is a macro to avoid include problems with THIS_MODULE */
#define device_schedule_callback(dev, func) \
device_schedule_callback_owner(dev, func, THIS_MODULE)

/* device resource management */
typedef void (*dr_release_t)(struct device *dev, void *res);
Expand Down Expand Up @@ -932,10 +926,7 @@ extern int device_online(struct device *dev);
extern struct device *__root_device_register(const char *name,
struct module *owner);

/*
* This is a macro to avoid include problems with THIS_MODULE,
* just as per what is done for device_schedule_callback() above.
*/
/* This is a macro to avoid include problems with THIS_MODULE */
#define root_device_register(name) \
__root_device_register(name, THIS_MODULE)

Expand Down
9 changes: 0 additions & 9 deletions include/linux/sysfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,9 +179,6 @@ struct sysfs_ops {

#ifdef CONFIG_SYSFS

int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *),
void *data, struct module *owner);

int __must_check sysfs_create_dir_ns(struct kobject *kobj, const void *ns);
void sysfs_remove_dir(struct kobject *kobj);
int __must_check sysfs_rename_dir_ns(struct kobject *kobj, const char *new_name,
Expand Down Expand Up @@ -255,12 +252,6 @@ static inline void sysfs_enable_ns(struct kernfs_node *kn)

#else /* CONFIG_SYSFS */

static inline int sysfs_schedule_callback(struct kobject *kobj,
void (*func)(void *), void *data, struct module *owner)
{
return -ENOSYS;
}

static inline int sysfs_create_dir_ns(struct kobject *kobj, const void *ns)
{
return 0;
Expand Down

0 comments on commit 60fbf2b

Please sign in to comment.