mirror of
https://github.com/coolsnowwolf/lede.git
synced 2025-04-16 14:23:38 +00:00
151 lines
4.9 KiB
Diff
151 lines
4.9 KiB
Diff
--- a/include/linux/device/class.h
|
|
+++ b/include/linux/device/class.h
|
|
@@ -49,6 +49,7 @@ struct fwnode_handle;
|
|
*/
|
|
struct class {
|
|
const char *name;
|
|
+ struct module *owner;
|
|
|
|
const struct attribute_group **class_groups;
|
|
const struct attribute_group **dev_groups;
|
|
--- a/include/linux/prandom.h
|
|
+++ b/include/linux/prandom.h
|
|
@@ -23,6 +23,12 @@ void prandom_seed_full_state(struct rnd_
|
|
#define prandom_init_once(pcpu_state) \
|
|
DO_ONCE(prandom_seed_full_state, (pcpu_state))
|
|
|
|
+/* Deprecated: use get_random_u32_below() instead. */
|
|
+static inline u32 prandom_u32_max(u32 ep_ro)
|
|
+{
|
|
+ return get_random_u32_below(ep_ro);
|
|
+}
|
|
+
|
|
/*
|
|
* Handle minimum values for seeds
|
|
*/
|
|
--- a/include/linux/u64_stats_sync.h
|
|
+++ b/include/linux/u64_stats_sync.h
|
|
@@ -214,4 +214,16 @@ static inline bool u64_stats_fetch_retry
|
|
return __u64_stats_fetch_retry(syncp, start);
|
|
}
|
|
|
|
+/* Obsolete interfaces */
|
|
+static inline unsigned int u64_stats_fetch_begin_irq(const struct u64_stats_sync *syncp)
|
|
+{
|
|
+ return u64_stats_fetch_begin(syncp);
|
|
+}
|
|
+
|
|
+static inline bool u64_stats_fetch_retry_irq(const struct u64_stats_sync *syncp,
|
|
+ unsigned int start)
|
|
+{
|
|
+ return u64_stats_fetch_retry(syncp, start);
|
|
+}
|
|
+
|
|
#endif /* _LINUX_U64_STATS_SYNC_H */
|
|
--- a/include/linux/netdevice.h
|
|
+++ b/include/linux/netdevice.h
|
|
@@ -2996,6 +2996,8 @@ int call_netdevice_notifiers(unsigned lo
|
|
int call_netdevice_notifiers_info(unsigned long val,
|
|
struct netdev_notifier_info *info);
|
|
|
|
+extern rwlock_t dev_base_lock; /* Device list lock */
|
|
+
|
|
#define for_each_netdev(net, d) \
|
|
list_for_each_entry(d, &(net)->dev_base_head, dev_list)
|
|
#define for_each_netdev_reverse(net, d) \
|
|
--- a/net/core/dev.c
|
|
+++ b/net/core/dev.c
|
|
@@ -172,6 +172,28 @@ static int call_netdevice_notifiers_exta
|
|
struct net_device *dev,
|
|
struct netlink_ext_ack *extack);
|
|
|
|
+/*
|
|
+ * The @dev_base_head list is protected by @dev_base_lock and the rtnl
|
|
+ * semaphore.
|
|
+ *
|
|
+ * Pure readers hold dev_base_lock for reading, or rcu_read_lock()
|
|
+ *
|
|
+ * Writers must hold the rtnl semaphore while they loop through the
|
|
+ * dev_base_head list, and hold dev_base_lock for writing when they do the
|
|
+ * actual updates. This allows pure readers to access the list even
|
|
+ * while a writer is preparing to update it.
|
|
+ *
|
|
+ * To put it another way, dev_base_lock is held for writing only to
|
|
+ * protect against pure readers; the rtnl semaphore provides the
|
|
+ * protection against other writers.
|
|
+ *
|
|
+ * See, for example usages, register_netdevice() and
|
|
+ * unregister_netdevice(), which must be called with the rtnl
|
|
+ * semaphore held.
|
|
+ */
|
|
+DEFINE_RWLOCK(dev_base_lock);
|
|
+EXPORT_SYMBOL(dev_base_lock);
|
|
+
|
|
static DEFINE_MUTEX(ifalias_mutex);
|
|
|
|
/* protects napi_hash addition/deletion and napi_gen_id */
|
|
@@ -403,10 +425,12 @@ static void list_netdevice(struct net_de
|
|
|
|
ASSERT_RTNL();
|
|
|
|
+ write_lock(&dev_base_lock);
|
|
list_add_tail_rcu(&dev->dev_list, &net->dev_base_head);
|
|
netdev_name_node_add(net, dev->name_node);
|
|
hlist_add_head_rcu(&dev->index_hlist,
|
|
dev_index_hash(net, dev->ifindex));
|
|
+ write_unlock(&dev_base_lock);
|
|
|
|
netdev_for_each_altname(dev, name_node)
|
|
netdev_name_node_add(net, name_node);
|
|
@@ -433,9 +457,11 @@ static void unlist_netdevice(struct net_
|
|
netdev_name_node_del(name_node);
|
|
|
|
/* Unlink dev from the device chain */
|
|
+ write_lock(&dev_base_lock);
|
|
list_del_rcu(&dev->dev_list);
|
|
netdev_name_node_del(dev->name_node);
|
|
hlist_del_rcu(&dev->index_hlist);
|
|
+ write_unlock(&dev_base_lock);
|
|
|
|
dev_base_seq_inc(dev_net(dev));
|
|
}
|
|
@@ -758,9 +784,9 @@ EXPORT_SYMBOL_GPL(dev_fill_forward_path)
|
|
* @net: the applicable net namespace
|
|
* @name: name to find
|
|
*
|
|
- * Find an interface by name. Must be called under RTNL semaphore.
|
|
- * If the name is found a pointer to the device is returned.
|
|
- * If the name is not found then %NULL is returned. The
|
|
+ * Find an interface by name. Must be called under RTNL semaphore
|
|
+ * or @dev_base_lock. If the name is found a pointer to the device
|
|
+ * is returned. If the name is not found then %NULL is returned. The
|
|
* reference counters are not incremented so the caller must be
|
|
* careful with locks.
|
|
*/
|
|
@@ -841,7 +867,8 @@ EXPORT_SYMBOL(netdev_get_by_name);
|
|
* Search for an interface by index. Returns %NULL if the device
|
|
* is not found or a pointer to the device. The device has not
|
|
* had its reference counter increased so the caller must be careful
|
|
- * about locking. The caller must hold the RTNL semaphore.
|
|
+ * about locking. The caller must hold either the RTNL semaphore
|
|
+ * or @dev_base_lock.
|
|
*/
|
|
|
|
struct net_device *__dev_get_by_index(struct net *net, int ifindex)
|
|
@@ -1259,11 +1286,15 @@ rollback:
|
|
|
|
netdev_adjacent_rename_links(dev, oldname);
|
|
|
|
+ write_lock(&dev_base_lock);
|
|
netdev_name_node_del(dev->name_node);
|
|
+ write_unlock(&dev_base_lock);
|
|
|
|
synchronize_net();
|
|
|
|
+ write_lock(&dev_base_lock);
|
|
netdev_name_node_add(net, dev->name_node);
|
|
+ write_unlock(&dev_base_lock);
|
|
|
|
ret = call_netdevice_notifiers(NETDEV_CHANGENAME, dev);
|
|
ret = notifier_to_errno(ret);
|