summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/nlattr.c31
-rw-r--r--lib/once.c30
2 files changed, 57 insertions, 4 deletions
diff --git a/lib/nlattr.c b/lib/nlattr.c
index 86029ad5ead4..40f22b177d69 100644
--- a/lib/nlattr.c
+++ b/lib/nlattr.c
@@ -159,6 +159,31 @@ void nla_get_range_unsigned(const struct nla_policy *pt,
}
}
+static u64 nla_get_attr_bo(const struct nla_policy *pt,
+ const struct nlattr *nla)
+{
+ switch (pt->type) {
+ case NLA_U16:
+ if (pt->network_byte_order)
+ return ntohs(nla_get_be16(nla));
+
+ return nla_get_u16(nla);
+ case NLA_U32:
+ if (pt->network_byte_order)
+ return ntohl(nla_get_be32(nla));
+
+ return nla_get_u32(nla);
+ case NLA_U64:
+ if (pt->network_byte_order)
+ return be64_to_cpu(nla_get_be64(nla));
+
+ return nla_get_u64(nla);
+ }
+
+ WARN_ON_ONCE(1);
+ return 0;
+}
+
static int nla_validate_range_unsigned(const struct nla_policy *pt,
const struct nlattr *nla,
struct netlink_ext_ack *extack,
@@ -172,12 +197,10 @@ static int nla_validate_range_unsigned(const struct nla_policy *pt,
value = nla_get_u8(nla);
break;
case NLA_U16:
- value = nla_get_u16(nla);
- break;
case NLA_U32:
- value = nla_get_u32(nla);
- break;
case NLA_U64:
+ value = nla_get_attr_bo(pt, nla);
+ break;
case NLA_MSECS:
value = nla_get_u64(nla);
break;
diff --git a/lib/once.c b/lib/once.c
index 59149bf3bfb4..2c306f0e891e 100644
--- a/lib/once.c
+++ b/lib/once.c
@@ -66,3 +66,33 @@ void __do_once_done(bool *done, struct static_key_true *once_key,
once_disable_jump(once_key, mod);
}
EXPORT_SYMBOL(__do_once_done);
+
+static DEFINE_MUTEX(once_mutex);
+
+bool __do_once_sleepable_start(bool *done)
+ __acquires(once_mutex)
+{
+ mutex_lock(&once_mutex);
+ if (*done) {
+ mutex_unlock(&once_mutex);
+ /* Keep sparse happy by restoring an even lock count on
+ * this mutex. In case we return here, we don't call into
+ * __do_once_done but return early in the DO_ONCE_SLEEPABLE() macro.
+ */
+ __acquire(once_mutex);
+ return false;
+ }
+
+ return true;
+}
+EXPORT_SYMBOL(__do_once_sleepable_start);
+
+void __do_once_sleepable_done(bool *done, struct static_key_true *once_key,
+ struct module *mod)
+ __releases(once_mutex)
+{
+ *done = true;
+ mutex_unlock(&once_mutex);
+ once_disable_jump(once_key, mod);
+}
+EXPORT_SYMBOL(__do_once_sleepable_done);