* [PATCH 1/3] security: keys: Replace time_t/timespec with time64_t
From: Baolin Wang @ 2017-08-09 2:51 UTC (permalink / raw)
To: dhowells, davem
Cc: james.l.morris, serge, marc.dionne, dan.carpenter, Jason, arnd,
broonie, keyrings, linux-kernel, linux-security-module, netdev,
baolin.wang
In-Reply-To: <cover.1502246501.git.baolin.wang@linaro.org>
The 'struct key' will use 'time_t' which we try to remove in the
kernel, since 'time_t' is not year 2038 safe on 32bit systems.
Also the 'struct keyring_search_context' will use 'timespec' type
to record current time, which is also not year 2038 safe on 32bit
systems.
Thus this patch replaces 'time_t' with 'time64_t' which is year 2038
safe for 'struct key', and replace 'timespec' with 'time64_t' for the
'struct keyring_search_context', since we only look at the the seconds
part of 'timespec' variable. Moreover we also change the codes where
using the 'time_t' and 'timespec', and we can get current time by
ktime_get_real_seconds() instead of current_kernel_time(), and use
'TIME64_MAX' macro to initialize the 'time64_t' type variable.
Especially in proc.c file, we have replaced 'unsigned long' and 'timespec'
type with 'u64' and 'time64_t' type to save the timeout value, which means
user will get one 'u64' type timeout value by issuing proc_keys_show()
function.
Signed-off-by: Baolin Wang <baolin.wang@linaro.org>
---
include/linux/key.h | 7 ++++---
security/keys/gc.c | 20 ++++++++++----------
security/keys/internal.h | 8 ++++----
security/keys/key.c | 19 ++++++-------------
security/keys/keyring.c | 18 +++++++++---------
security/keys/permission.c | 3 +--
security/keys/proc.c | 20 ++++++++++----------
security/keys/process_keys.c | 2 +-
8 files changed, 45 insertions(+), 52 deletions(-)
diff --git a/include/linux/key.h b/include/linux/key.h
index 0441141..6d10f84 100644
--- a/include/linux/key.h
+++ b/include/linux/key.h
@@ -24,6 +24,7 @@
#include <linux/atomic.h>
#include <linux/assoc_array.h>
#include <linux/refcount.h>
+#include <linux/time64.h>
#ifdef __KERNEL__
#include <linux/uidgid.h>
@@ -157,10 +158,10 @@ struct key {
struct key_user *user; /* owner of this key */
void *security; /* security data for this key */
union {
- time_t expiry; /* time at which key expires (or 0) */
- time_t revoked_at; /* time at which key was revoked */
+ time64_t expiry; /* time at which key expires (or 0) */
+ time64_t revoked_at; /* time at which key was revoked */
};
- time_t last_used_at; /* last time used for LRU keyring discard */
+ time64_t last_used_at; /* last time used for LRU keyring discard */
kuid_t uid;
kgid_t gid;
key_perm_t perm; /* access permissions */
diff --git a/security/keys/gc.c b/security/keys/gc.c
index 87cb260..c99700e 100644
--- a/security/keys/gc.c
+++ b/security/keys/gc.c
@@ -32,7 +32,7 @@
static void key_gc_timer_func(unsigned long);
static DEFINE_TIMER(key_gc_timer, key_gc_timer_func, 0, 0);
-static time_t key_gc_next_run = LONG_MAX;
+static time64_t key_gc_next_run = TIME64_MAX;
static struct key_type *key_gc_dead_keytype;
static unsigned long key_gc_flags;
@@ -53,12 +53,12 @@ struct key_type key_type_dead = {
* Schedule a garbage collection run.
* - time precision isn't particularly important
*/
-void key_schedule_gc(time_t gc_at)
+void key_schedule_gc(time64_t gc_at)
{
unsigned long expires;
- time_t now = current_kernel_time().tv_sec;
+ time64_t now = ktime_get_real_seconds();
- kenter("%ld", gc_at - now);
+ kenter("%lld", gc_at - now);
if (gc_at <= now || test_bit(KEY_GC_REAP_KEYTYPE, &key_gc_flags)) {
kdebug("IMMEDIATE");
@@ -87,7 +87,7 @@ void key_schedule_gc_links(void)
static void key_gc_timer_func(unsigned long data)
{
kenter("");
- key_gc_next_run = LONG_MAX;
+ key_gc_next_run = TIME64_MAX;
key_schedule_gc_links();
}
@@ -184,11 +184,11 @@ static void key_garbage_collector(struct work_struct *work)
struct rb_node *cursor;
struct key *key;
- time_t new_timer, limit;
+ time64_t new_timer, limit;
kenter("[%lx,%x]", key_gc_flags, gc_state);
- limit = current_kernel_time().tv_sec;
+ limit = ktime_get_real_seconds();
if (limit > key_gc_delay)
limit -= key_gc_delay;
else
@@ -204,7 +204,7 @@ static void key_garbage_collector(struct work_struct *work)
gc_state |= KEY_GC_REAPING_DEAD_1;
kdebug("new pass %x", gc_state);
- new_timer = LONG_MAX;
+ new_timer = TIME64_MAX;
/* As only this function is permitted to remove things from the key
* serial tree, if cursor is non-NULL then it will always point to a
@@ -235,7 +235,7 @@ static void key_garbage_collector(struct work_struct *work)
if (gc_state & KEY_GC_SET_TIMER) {
if (key->expiry > limit && key->expiry < new_timer) {
- kdebug("will expire %x in %ld",
+ kdebug("will expire %x in %lld",
key_serial(key), key->expiry - limit);
new_timer = key->expiry;
}
@@ -276,7 +276,7 @@ static void key_garbage_collector(struct work_struct *work)
*/
kdebug("pass complete");
- if (gc_state & KEY_GC_SET_TIMER && new_timer != (time_t)LONG_MAX) {
+ if (gc_state & KEY_GC_SET_TIMER && new_timer != (time64_t)TIME64_MAX) {
new_timer += key_gc_delay;
key_schedule_gc(new_timer);
}
diff --git a/security/keys/internal.h b/security/keys/internal.h
index 91bc621..e23ffbc 100644
--- a/security/keys/internal.h
+++ b/security/keys/internal.h
@@ -130,7 +130,7 @@ struct keyring_search_context {
int skipped_ret;
bool possessed;
key_ref_t result;
- struct timespec now;
+ time64_t now;
};
extern bool key_default_cmp(const struct key *key,
@@ -169,10 +169,10 @@ extern key_ref_t lookup_user_key(key_serial_t id, unsigned long flags,
extern struct work_struct key_gc_work;
extern unsigned key_gc_delay;
-extern void keyring_gc(struct key *keyring, time_t limit);
+extern void keyring_gc(struct key *keyring, time64_t limit);
extern void keyring_restriction_gc(struct key *keyring,
struct key_type *dead_type);
-extern void key_schedule_gc(time_t gc_at);
+extern void key_schedule_gc(time64_t gc_at);
extern void key_schedule_gc_links(void);
extern void key_gc_keytype(struct key_type *ktype);
@@ -211,7 +211,7 @@ extern struct key *request_key_auth_new(struct key *target,
/*
* Determine whether a key is dead.
*/
-static inline bool key_is_dead(const struct key *key, time_t limit)
+static inline bool key_is_dead(const struct key *key, time64_t limit)
{
return
key->flags & ((1 << KEY_FLAG_DEAD) |
diff --git a/security/keys/key.c b/security/keys/key.c
index 83da68d..291a67c 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -556,7 +556,6 @@ int key_reject_and_link(struct key *key,
struct key *authkey)
{
struct assoc_array_edit *edit;
- struct timespec now;
int ret, awaken, link_ret = 0;
key_check(key);
@@ -582,8 +581,7 @@ int key_reject_and_link(struct key *key,
smp_wmb();
set_bit(KEY_FLAG_NEGATIVE, &key->flags);
set_bit(KEY_FLAG_INSTANTIATED, &key->flags);
- now = current_kernel_time();
- key->expiry = now.tv_sec + timeout;
+ key->expiry = ktime_get_real_seconds() + timeout;
key_schedule_gc(key->expiry + key_gc_delay);
if (test_and_clear_bit(KEY_FLAG_USER_CONSTRUCT, &key->flags))
@@ -699,16 +697,13 @@ struct key_type *key_type_lookup(const char *type)
void key_set_timeout(struct key *key, unsigned timeout)
{
- struct timespec now;
- time_t expiry = 0;
+ time64_t expiry = 0;
/* make the changes with the locks held to prevent races */
down_write(&key->sem);
- if (timeout > 0) {
- now = current_kernel_time();
- expiry = now.tv_sec + timeout;
- }
+ if (timeout > 0)
+ expiry = ktime_get_real_seconds() + timeout;
key->expiry = expiry;
key_schedule_gc(key->expiry + key_gc_delay);
@@ -1007,8 +1002,7 @@ int key_update(key_ref_t key_ref, const void *payload, size_t plen)
*/
void key_revoke(struct key *key)
{
- struct timespec now;
- time_t time;
+ time64_t time;
key_check(key);
@@ -1023,8 +1017,7 @@ void key_revoke(struct key *key)
key->type->revoke(key);
/* set the death time to no more than the expiry time */
- now = current_kernel_time();
- time = now.tv_sec;
+ time = ktime_get_real_seconds();
if (key->revoked_at == 0 || key->revoked_at > time) {
key->revoked_at = time;
key_schedule_gc(key->revoked_at + key_gc_delay);
diff --git a/security/keys/keyring.c b/security/keys/keyring.c
index de81793..2d82088 100644
--- a/security/keys/keyring.c
+++ b/security/keys/keyring.c
@@ -576,7 +576,7 @@ static int keyring_search_iterator(const void *object, void *iterator_data)
goto skipped;
}
- if (key->expiry && ctx->now.tv_sec >= key->expiry) {
+ if (key->expiry && ctx->now >= key->expiry) {
if (!(ctx->flags & KEYRING_SEARCH_SKIP_EXPIRED))
ctx->result = ERR_PTR(-EKEYEXPIRED);
kleave(" = %d [expire]", ctx->skipped_ret);
@@ -837,10 +837,10 @@ static bool search_nested_keyrings(struct key *keyring,
key = key_ref_to_ptr(ctx->result);
key_check(key);
if (!(ctx->flags & KEYRING_SEARCH_NO_UPDATE_TIME)) {
- key->last_used_at = ctx->now.tv_sec;
- keyring->last_used_at = ctx->now.tv_sec;
+ key->last_used_at = ctx->now;
+ keyring->last_used_at = ctx->now;
while (sp > 0)
- stack[--sp].keyring->last_used_at = ctx->now.tv_sec;
+ stack[--sp].keyring->last_used_at = ctx->now;
}
kleave(" = true");
return true;
@@ -901,7 +901,7 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref,
}
rcu_read_lock();
- ctx->now = current_kernel_time();
+ ctx->now = ktime_get_real_seconds();
if (search_nested_keyrings(keyring, ctx))
__key_get(key_ref_to_ptr(ctx->result));
rcu_read_unlock();
@@ -1147,7 +1147,7 @@ struct key *find_keyring_by_name(const char *name, bool skip_perm_check)
* (ie. it has a zero usage count) */
if (!refcount_inc_not_zero(&keyring->usage))
continue;
- keyring->last_used_at = current_kernel_time().tv_sec;
+ keyring->last_used_at = ktime_get_real_seconds();
goto out;
}
}
@@ -1487,7 +1487,7 @@ static void keyring_revoke(struct key *keyring)
static bool keyring_gc_select_iterator(void *object, void *iterator_data)
{
struct key *key = keyring_ptr_to_key(object);
- time_t *limit = iterator_data;
+ time64_t *limit = iterator_data;
if (key_is_dead(key, *limit))
return false;
@@ -1498,7 +1498,7 @@ static bool keyring_gc_select_iterator(void *object, void *iterator_data)
static int keyring_gc_check_iterator(const void *object, void *iterator_data)
{
const struct key *key = keyring_ptr_to_key(object);
- time_t *limit = iterator_data;
+ time64_t *limit = iterator_data;
key_check(key);
return key_is_dead(key, *limit);
@@ -1510,7 +1510,7 @@ static int keyring_gc_check_iterator(const void *object, void *iterator_data)
* Not called with any locks held. The keyring's key struct will not be
* deallocated under us as only our caller may deallocate it.
*/
-void keyring_gc(struct key *keyring, time_t limit)
+void keyring_gc(struct key *keyring, time64_t limit)
{
int result;
diff --git a/security/keys/permission.c b/security/keys/permission.c
index 732cc0b..507b1d41 100644
--- a/security/keys/permission.c
+++ b/security/keys/permission.c
@@ -100,8 +100,7 @@ int key_validate(const struct key *key)
/* check it hasn't expired */
if (key->expiry) {
- struct timespec now = current_kernel_time();
- if (now.tv_sec >= key->expiry)
+ if (ktime_get_real_seconds() >= key->expiry)
return -EKEYEXPIRED;
}
diff --git a/security/keys/proc.c b/security/keys/proc.c
index bf08d02..95c8720 100644
--- a/security/keys/proc.c
+++ b/security/keys/proc.c
@@ -178,8 +178,8 @@ static int proc_keys_show(struct seq_file *m, void *v)
{
struct rb_node *_p = v;
struct key *key = rb_entry(_p, struct key, serial_node);
- struct timespec now;
- unsigned long timo;
+ time64_t now;
+ u64 timo;
key_ref_t key_ref, skey_ref;
char xbuf[16];
int rc;
@@ -216,28 +216,28 @@ static int proc_keys_show(struct seq_file *m, void *v)
if (rc < 0)
return 0;
- now = current_kernel_time();
+ now = ktime_get_real_seconds();
rcu_read_lock();
/* come up with a suitable timeout value */
if (key->expiry == 0) {
memcpy(xbuf, "perm", 5);
- } else if (now.tv_sec >= key->expiry) {
+ } else if (now >= key->expiry) {
memcpy(xbuf, "expd", 5);
} else {
- timo = key->expiry - now.tv_sec;
+ timo = key->expiry - now;
if (timo < 60)
- sprintf(xbuf, "%lus", timo);
+ sprintf(xbuf, "%llus", timo);
else if (timo < 60*60)
- sprintf(xbuf, "%lum", timo / 60);
+ sprintf(xbuf, "%llum", div_u64(timo, 60));
else if (timo < 60*60*24)
- sprintf(xbuf, "%luh", timo / (60*60));
+ sprintf(xbuf, "%lluh", div_u64(timo, 60 * 60));
else if (timo < 60*60*24*7)
- sprintf(xbuf, "%lud", timo / (60*60*24));
+ sprintf(xbuf, "%llud", div_u64(timo, 60 * 60 * 24));
else
- sprintf(xbuf, "%luw", timo / (60*60*24*7));
+ sprintf(xbuf, "%lluw", div_u64(timo, 60 * 60 * 24 * 7));
}
#define showflag(KEY, LETTER, FLAG) \
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index 86bced9..c691e09 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -736,7 +736,7 @@ key_ref_t lookup_user_key(key_serial_t id, unsigned long lflags,
if (ret < 0)
goto invalid_key;
- key->last_used_at = current_kernel_time().tv_sec;
+ key->last_used_at = ktime_get_real_seconds();
error:
put_cred(ctx.cred);
--
1.7.9.5
^ permalink raw reply related
* [PATCH 2/3] security: keys: Replace time_t with time64_t for struct key_preparsed_payload
From: Baolin Wang @ 2017-08-09 2:51 UTC (permalink / raw)
To: dhowells, davem
Cc: james.l.morris, serge, marc.dionne, dan.carpenter, Jason, arnd,
broonie, keyrings, linux-kernel, linux-security-module, netdev,
baolin.wang
In-Reply-To: <cover.1502246501.git.baolin.wang@linaro.org>
The 'struct key_preparsed_payload' will use 'time_t' which we will
try to remove in the kernel, since 'time_t' is not year 2038 safe on
32bits systems.
Thus this patch replaces 'time_t' with 'time64_t' which is year 2038
safe on 32 bits system for 'struct key_preparsed_payload', moreover
we should use the 'TIME64_MAX' macro to initialize the 'time64_t'
type variable.
Signed-off-by: Baolin Wang <baolin.wang@linaro.org>
---
include/linux/key-type.h | 2 +-
security/keys/key.c | 8 ++++----
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/include/linux/key-type.h b/include/linux/key-type.h
index 8496cf6..4beb006 100644
--- a/include/linux/key-type.h
+++ b/include/linux/key-type.h
@@ -44,7 +44,7 @@ struct key_preparsed_payload {
const void *data; /* Raw data */
size_t datalen; /* Raw datalen */
size_t quotalen; /* Quota length for proposed payload */
- time_t expiry; /* Expiry time of key */
+ time64_t expiry; /* Expiry time of key */
};
typedef int (*request_key_actor_t)(struct key_construction *key,
diff --git a/security/keys/key.c b/security/keys/key.c
index 291a67c..d5c8941 100644
--- a/security/keys/key.c
+++ b/security/keys/key.c
@@ -446,7 +446,7 @@ static int __key_instantiate_and_link(struct key *key,
if (authkey)
key_revoke(authkey);
- if (prep->expiry != TIME_T_MAX) {
+ if (prep->expiry != TIME64_MAX) {
key->expiry = prep->expiry;
key_schedule_gc(prep->expiry + key_gc_delay);
}
@@ -492,7 +492,7 @@ int key_instantiate_and_link(struct key *key,
prep.data = data;
prep.datalen = datalen;
prep.quotalen = key->type->def_datalen;
- prep.expiry = TIME_T_MAX;
+ prep.expiry = TIME64_MAX;
if (key->type->preparse) {
ret = key->type->preparse(&prep);
if (ret < 0)
@@ -834,7 +834,7 @@ key_ref_t key_create_or_update(key_ref_t keyring_ref,
prep.data = payload;
prep.datalen = plen;
prep.quotalen = index_key.type->def_datalen;
- prep.expiry = TIME_T_MAX;
+ prep.expiry = TIME64_MAX;
if (index_key.type->preparse) {
ret = index_key.type->preparse(&prep);
if (ret < 0) {
@@ -968,7 +968,7 @@ int key_update(key_ref_t key_ref, const void *payload, size_t plen)
prep.data = payload;
prep.datalen = plen;
prep.quotalen = key->type->def_datalen;
- prep.expiry = TIME_T_MAX;
+ prep.expiry = TIME64_MAX;
if (key->type->preparse) {
ret = key->type->preparse(&prep);
if (ret < 0)
--
1.7.9.5
^ permalink raw reply related
* [PATCH 3/3] net: rxrpc: Replace time_t type with time64_t type
From: Baolin Wang @ 2017-08-09 2:51 UTC (permalink / raw)
To: dhowells, davem
Cc: james.l.morris, serge, marc.dionne, dan.carpenter, Jason, arnd,
broonie, keyrings, linux-kernel, linux-security-module, netdev,
baolin.wang
In-Reply-To: <cover.1502246501.git.baolin.wang@linaro.org>
Since the 'expiry' variable of 'struct key_preparsed_payload' has been
changed to 'time64_t' type, which is year 2038 safe on 32bits system.
In net/rxrpc subsystem, we need convert 'u32' type to 'time64_t' type
when copying ticket expires time to 'prep->expiry', then this patch
introduces two helper functions to help convert 'u32' to 'time64_t'
type.
This patch also uses ktime_get_real_seconds() to get current time instead
of get_seconds() which is not year 2038 safe on 32bits system.
Signed-off-by: Baolin Wang <baolin.wang@linaro.org>
---
include/keys/rxrpc-type.h | 21 +++++++++++++++++++++
net/rxrpc/ar-internal.h | 2 +-
net/rxrpc/key.c | 22 ++++++++++++++--------
net/rxrpc/rxkad.c | 14 +++++++-------
4 files changed, 43 insertions(+), 16 deletions(-)
diff --git a/include/keys/rxrpc-type.h b/include/keys/rxrpc-type.h
index 5de0673..76421e2 100644
--- a/include/keys/rxrpc-type.h
+++ b/include/keys/rxrpc-type.h
@@ -127,4 +127,25 @@ struct rxrpc_key_data_v1 {
#define AFSTOKEN_K5_ADDRESSES_MAX 16 /* max K5 addresses */
#define AFSTOKEN_K5_AUTHDATA_MAX 16 /* max K5 pieces of auth data */
+/*
+ * truncate a time64_t to the range from 1970 to 2106 as
+ * in the network protocol
+ */
+static inline u32 rxrpc_time64_to_u32(time64_t time)
+{
+ if (time < 0)
+ return 0;
+
+ if (time > UINT_MAX)
+ return UINT_MAX;
+
+ return (u32)time;
+}
+
+/* extend u32 back to time64_t using the same 1970-2106 range */
+static inline time64_t rxrpc_u32_to_time64(u32 time)
+{
+ return (time64_t)time;
+}
+
#endif /* _KEYS_RXRPC_TYPE_H */
diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h
index 69b9733..3c11443 100644
--- a/net/rxrpc/ar-internal.h
+++ b/net/rxrpc/ar-internal.h
@@ -894,7 +894,7 @@ void rxrpc_new_incoming_connection(struct rxrpc_sock *,
int rxrpc_request_key(struct rxrpc_sock *, char __user *, int);
int rxrpc_server_keyring(struct rxrpc_sock *, char __user *, int);
-int rxrpc_get_server_data_key(struct rxrpc_connection *, const void *, time_t,
+int rxrpc_get_server_data_key(struct rxrpc_connection *, const void *, time64_t,
u32);
/*
diff --git a/net/rxrpc/key.c b/net/rxrpc/key.c
index 5436922..e2d3661 100644
--- a/net/rxrpc/key.c
+++ b/net/rxrpc/key.c
@@ -92,6 +92,7 @@ static int rxrpc_preparse_xdr_rxkad(struct key_preparsed_payload *prep,
const __be32 *xdr, unsigned int toklen)
{
struct rxrpc_key_token *token, **pptoken;
+ time64_t expiry;
size_t plen;
u32 tktlen;
@@ -158,8 +159,9 @@ static int rxrpc_preparse_xdr_rxkad(struct key_preparsed_payload *prep,
pptoken = &(*pptoken)->next)
continue;
*pptoken = token;
- if (token->kad->expiry < prep->expiry)
- prep->expiry = token->kad->expiry;
+ expiry = rxrpc_u32_to_time64(token->kad->expiry);
+ if (expiry < prep->expiry)
+ prep->expiry = expiry;
_leave(" = 0");
return 0;
@@ -433,6 +435,7 @@ static int rxrpc_preparse_xdr_rxk5(struct key_preparsed_payload *prep,
struct rxrpc_key_token *token, **pptoken;
struct rxk5_key *rxk5;
const __be32 *end_xdr = xdr + (toklen >> 2);
+ time64_t expiry;
int ret;
_enter(",{%x,%x,%x,%x},%u",
@@ -533,8 +536,9 @@ static int rxrpc_preparse_xdr_rxk5(struct key_preparsed_payload *prep,
pptoken = &(*pptoken)->next)
continue;
*pptoken = token;
- if (token->kad->expiry < prep->expiry)
- prep->expiry = token->kad->expiry;
+ expiry = rxrpc_u32_to_time64(token->kad->expiry);
+ if (expiry < prep->expiry)
+ prep->expiry = expiry;
_leave(" = 0");
return 0;
@@ -691,6 +695,7 @@ static int rxrpc_preparse(struct key_preparsed_payload *prep)
{
const struct rxrpc_key_data_v1 *v1;
struct rxrpc_key_token *token, **pp;
+ time64_t expiry;
size_t plen;
u32 kver;
int ret;
@@ -777,8 +782,9 @@ static int rxrpc_preparse(struct key_preparsed_payload *prep)
while (*pp)
pp = &(*pp)->next;
*pp = token;
- if (token->kad->expiry < prep->expiry)
- prep->expiry = token->kad->expiry;
+ expiry = rxrpc_u32_to_time64(token->kad->expiry);
+ if (expiry < prep->expiry)
+ prep->expiry = expiry;
token = NULL;
ret = 0;
@@ -955,7 +961,7 @@ int rxrpc_server_keyring(struct rxrpc_sock *rx, char __user *optval,
*/
int rxrpc_get_server_data_key(struct rxrpc_connection *conn,
const void *session_key,
- time_t expiry,
+ time64_t expiry,
u32 kvno)
{
const struct cred *cred = current_cred();
@@ -982,7 +988,7 @@ int rxrpc_get_server_data_key(struct rxrpc_connection *conn,
data.kver = 1;
data.v1.security_index = RXRPC_SECURITY_RXKAD;
data.v1.ticket_length = 0;
- data.v1.expiry = expiry;
+ data.v1.expiry = rxrpc_time64_to_u32(expiry);
data.v1.kvno = 0;
memcpy(&data.v1.session_key, session_key, sizeof(data.v1.session_key));
diff --git a/net/rxrpc/rxkad.c b/net/rxrpc/rxkad.c
index 46d1a1f..34c86d2 100644
--- a/net/rxrpc/rxkad.c
+++ b/net/rxrpc/rxkad.c
@@ -854,7 +854,7 @@ static int rxkad_decrypt_ticket(struct rxrpc_connection *conn,
struct sk_buff *skb,
void *ticket, size_t ticket_len,
struct rxrpc_crypt *_session_key,
- time_t *_expiry,
+ time64_t *_expiry,
u32 *_abort_code)
{
struct skcipher_request *req;
@@ -864,7 +864,7 @@ static int rxkad_decrypt_ticket(struct rxrpc_connection *conn,
struct in_addr addr;
unsigned int life;
const char *eproto;
- time_t issue, now;
+ time64_t issue, now;
bool little_endian;
int ret;
u32 abort_code;
@@ -960,15 +960,15 @@ static int rxkad_decrypt_ticket(struct rxrpc_connection *conn,
if (little_endian) {
__le32 stamp;
memcpy(&stamp, p, 4);
- issue = le32_to_cpu(stamp);
+ issue = rxrpc_u32_to_time64(le32_to_cpu(stamp));
} else {
__be32 stamp;
memcpy(&stamp, p, 4);
- issue = be32_to_cpu(stamp);
+ issue = rxrpc_u32_to_time64(be32_to_cpu(stamp));
}
p += 4;
- now = get_seconds();
- _debug("KIV ISSUE: %lx [%lx]", issue, now);
+ now = ktime_get_real_seconds();
+ _debug("KIV ISSUE: %llx [%llx]", issue, now);
/* check the ticket is in date */
if (issue > now) {
@@ -1053,7 +1053,7 @@ static int rxkad_verify_response(struct rxrpc_connection *conn,
struct rxrpc_skb_priv *sp = rxrpc_skb(skb);
struct rxrpc_crypt session_key;
const char *eproto;
- time_t expiry;
+ time64_t expiry;
void *ticket;
u32 abort_code, version, kvno, ticket_len, level;
__be32 csum;
--
1.7.9.5
^ permalink raw reply related
* Re: [PATCH v9 1/4] PCI: Add new PCIe Fabric End Node flag, PCI_DEV_FLAGS_NO_RELAXED_ORDERING
From: Bjorn Helgaas @ 2017-08-09 3:02 UTC (permalink / raw)
To: Casey Leedom
Cc: Ding Tianhong, ashok.raj@intel.com, bhelgaas@google.com,
Michael Werner, Ganesh GR, asit.k.mallick@intel.com,
patrick.j.cramer@intel.com, Suravee.Suthikulpanit@amd.com,
Bob.Shaw@amd.com, l.stach@pengutronix.de, amira@mellanox.com,
gabriele.paoloni@huawei.com, David.Laight@aculab.com,
jeffrey.t.kirsher@intel.com, catalin.marinas@arm.com,
"will.deacon@arm.com" <will.deacon
In-Reply-To: <MWHPR12MB1600249E96C320D5472F77ADC88B0@MWHPR12MB1600.namprd12.prod.outlook.com>
On Wed, Aug 09, 2017 at 01:40:01AM +0000, Casey Leedom wrote:
> | From: Bjorn Helgaas <helgaas@kernel.org>
> | Sent: Tuesday, August 8, 2017 4:22 PM
> |
> | This needs to include a link to the Intel spec
> | (https://software.intel.com/sites/default/files/managed/9e/bc/64-ia-32-architectures-optimization-manual.pdf,
> | sec 3.9.1).
>
> In the commit message or as a comment? Regardless, I agree. It's always
> nice to be able to go back and see what the official documentation says.
> However, that said, links on the internet are ... fragile as time goes by,
> so we might want to simply quote section 3.9.1 in the commit message since
> it's relatively short:
>
> 3.9.1 Optimizing PCIe Performance for Accesses Toward Coherent Memory
> and Toward MMIO Regions (P2P)
>
> In order to maximize performance for PCIe devices in the processors
> listed in Table 3-6 below, the soft- ware should determine whether the
> accesses are toward coherent memory (system memory) or toward MMIO
> regions (P2P access to other devices). If the access is toward MMIO
> region, then software can command HW to set the RO bit in the TLP
> header, as this would allow hardware to achieve maximum throughput for
> these types of accesses. For accesses toward coherent memory, software
> can command HW to clear the RO bit in the TLP header (no RO), as this
> would allow hardware to achieve maximum throughput for these types of
> accesses.
>
> Table 3-6. Intel Processor CPU RP Device IDs for Processors Optimizing
> PCIe Performance
>
> Processor CPU RP Device IDs
>
> Intel Xeon processors based on 6F01H-6F0EH
> Broadwell microarchitecture
>
> Intel Xeon processors based on 2F01H-2F0EH
> Haswell microarchitecture
Agreed, links are prone to being broken. I would include in the
changelog the complete title and order number, along with the link as
a footnote. Wouldn't hurt to quote the section too, since it's short.
> | It should also include a pointer to the AMD erratum, if available, or
> | at least some reference to how we know it doesn't obey the rules.
>
> Getting an ACK from AMD seems like a forlorn cause at this point. My
> contact was Bob Shaw <Bob.Shaw@amd.com> and he stopped responding to me
> messages almost a year ago saying that all of AMD's energies were being
> redirected towards upcoming x86 products (likely Ryzen as we now know). As
> far as I can tell AMD has walked away from their A1100 (AKA "Seattle") ARM
> SoC.
>
> On the specific issue, I can certainly write up somthing even more
> extensive than I wrote up for the comment in drivers/pci/quirks.c. Please
> review the comment I wrote up and tell me if you'd like something even more
> detailed -- I'm usually acused of writing comments which are too long, so
> this would be a new one on me ... :-)
If you have any bug reports with info about how you debugged it and
concluded that Seattle is broken, you could include a link (probably
in the changelog). But if there isn't anything, there isn't anything.
I might reorganize those patches as:
1) Add a PCI_DEV_FLAGS_RELAXED_ORDERING_BROKEN flag, the quirk that
sets it, and the current patch [2/4] that uses it.
2) Add the Intel DECLARE_PCI_FIXUP_CLASS_EARLY()s with the Intel
details.
3) Add the AMD DECLARE_PCI_FIXUP_CLASS_EARLY()s with the AMD
details.
^ permalink raw reply
* Re: [PATCH v9 2/4] PCI: Disable PCIe Relaxed Ordering if unsupported
From: Bjorn Helgaas @ 2017-08-09 3:25 UTC (permalink / raw)
To: Ding Tianhong
Cc: mark.rutland, gabriele.paoloni, asit.k.mallick, catalin.marinas,
will.deacon, linuxarm, alexander.duyck, ashok.raj,
jeffrey.t.kirsher, linux-pci, ganeshgr, Bob.Shaw, leedom,
patrick.j.cramer, bhelgaas, werner, linux-arm-kernel, amira,
netdev, linux-kernel, David.Laight, Suravee.Suthikulpanit,
robin.murphy, davem, l.stach
In-Reply-To: <20170809022239.GP16580@bhelgaas-glaptop.roam.corp.google.com>
On Tue, Aug 08, 2017 at 09:22:39PM -0500, Bjorn Helgaas wrote:
> On Sat, Aug 05, 2017 at 03:15:11PM +0800, Ding Tianhong wrote:
> > When bit4 is set in the PCIe Device Control register, it indicates
> > whether the device is permitted to use relaxed ordering.
> > On some platforms using relaxed ordering can have performance issues or
> > due to erratum can cause data-corruption. In such cases devices must avoid
> > using relaxed ordering.
> >
> > This patch checks if there is any node in the hierarchy that indicates that
> > using relaxed ordering is not safe.
...
> > +EXPORT_SYMBOL(pcie_relaxed_ordering_supported);
>
> This is misnamed. This doesn't tell us anything about whether the
> device *supports* relaxed ordering. It only tells us whether the
> device is *permitted* to use it.
>
> When a device initiates a transaction, the hardware should set the RO
> bit in the TLP with logic something like this:
>
> RO = <this Function supports relaxed ordering> &&
> <this transaction doesn't require strong write ordering> &&
> <PCI_EXP_DEVCTL_RELAX_EN is set>
>
> The issue you're fixing is that some Completers don't handle RO
> correctly. The determining factor is not the Requester, but the
> Completer (for this series, a Root Port). So I think this should be
> something like:
>
> int pcie_relaxed_ordering_broken(struct pci_dev *completer)
> {
> if (!completer)
> return 0;
>
> return completer->dev_flags & PCI_DEV_FLAGS_NO_RELAXED_ORDERING;
> }
>
> and the caller should do something like this:
>
> if (pcie_relaxed_ordering_broken(pci_find_pcie_root_port(pdev)))
> adapter->flags |= ROOT_NO_RELAXED_ORDERING;
>
> That way it's obvious where the issue is, and it's obvious that the
> answer might be different for peer-to-peer transactions than it is for
> transactions to the root port, i.e., to coherent memory.
After looking at the driver, I wonder if it would be simpler like
this:
int pcie_relaxed_ordering_enabled(struct pci_dev *dev)
{
u16 ctl;
pcie_capability_read_word(dev, PCI_EXP_DEVCTL, &ctl);
return ctl & PCI_EXP_DEVCTL_RELAX_EN;
}
EXPORT_SYMBOL(pcie_relaxed_ordering_enabled);
static void pci_configure_relaxed_ordering(struct pci_dev *dev)
{
struct pci_dev *root;
if (dev->is_virtfn)
return; /* PCI_EXP_DEVCTL_RELAX_EN is RsvdP in VFs */
if (!pcie_relaxed_ordering_enabled(dev))
return;
/*
* For now, we only deal with Relaxed Ordering issues with Root
* Ports. Peer-to-peer DMA is another can of worms.
*/
root = pci_find_pcie_root_port(dev);
if (!root)
return;
if (root->relaxed_ordering_broken)
pcie_capability_clear_word(dev, PCI_EXP_DEVCTL,
PCI_EXP_DEVCTL_RELAX_EN);
}
This doesn't check every intervening switch, but I don't think we know
about any issues except with root ports.
And the driver could do:
if (!pcie_relaxed_ordering_enabled(pdev))
adapter->flags |= ROOT_NO_RELAXED_ORDERING;
The driver code wouldn't show anything about coherent memory vs.
peer-to-peer, but we really don't have a clue about how to handle that
yet anyway.
I guess this is back to exactly what you proposed, except that I
changed the name of pcie_relaxed_ordering_supported() to
pcie_relaxed_ordering_enabled(), which I think is slightly more
specific from the device's point of view.
Bjorn
^ permalink raw reply
* Re: [PATCH RFC v2 3/5] samples/bpf: Fix inline asm issues building samples on arm64
From: David Miller @ 2017-08-09 3:35 UTC (permalink / raw)
To: joelaf; +Cc: linux-kernel, fengc, alison, Juri.Lelli, ast, daniel, netdev
In-Reply-To: <CAJWu+orPBSozHo6PDnvg9+RzmYVO=rwwNZk45kHFsBJmy-3A-Q@mail.gmail.com>
From: Joel Fernandes <joelaf@google.com>
Date: Mon, 7 Aug 2017 18:20:49 -0700
> On Mon, Aug 7, 2017 at 11:28 AM, David Miller <davem@davemloft.net> wrote:
>> The amount of hellish hacks we are adding to deal with this is getting
>> way out of control.
>
> I agree with you that hellish hacks are being added which is why it
> keeps breaking. I think one of the things my series does is to add
> back inclusion of asm headers that were previously removed (that is
> the worst hellish hack in my opinion that existing in mainline). So in
> that respect my patch is an improvement and makes it possible to build
> for arm64 platforms (which is currently broken in mainline).
Yeah that is a problem.
Perhaps another avenue of attack is to separate "type" header files from
stuff that has functiond declarations and inline assembler code.
^ permalink raw reply
* Re: [PATCH net-next] cxgb4: Clear On FLASH config file after a FW upgrade
From: David Miller @ 2017-08-09 3:36 UTC (permalink / raw)
To: ganeshgr; +Cc: netdev, nirranjan, indranil, venkatesh, leedom, arjun
In-Reply-To: <1502171452-32389-1-git-send-email-ganeshgr@chelsio.com>
From: Ganesh Goudar <ganeshgr@chelsio.com>
Date: Tue, 8 Aug 2017 11:20:52 +0530
> From: Arjun Vynipadath <arjun@chelsio.com>
>
> Because Firmware and the Firmware Configuration File need to be
> in sync; clear out any On-FLASH Firmware Configuration File when new
> Firmware is loaded. This will avoid difficult to diagnose and fix
> problems with a mis-matched Firmware Configuration File which prevents the
> adapter from being initialized.
>
> Original work by: Casey Leedom <leedom@chelsio.com>
> Signed-off-by: Arjun Vynipadath <arjun@chelsio.com>
> Signed-off-by: Ganesh Goudar <ganeshgr@chelsio.com>
Applied, thanks.
^ permalink raw reply
* Re: [PATCHv3 net] net: sched: set xt_tgchk_param par.net properly in ipt_init_target
From: David Miller @ 2017-08-09 3:38 UTC (permalink / raw)
To: lucien.xin; +Cc: netdev, jiri, xiyou.wangcong
In-Reply-To: <7aa6e3f47ea0feb6f348b4de20fc6503e8c8e25b.1502177125.git.lucien.xin@gmail.com>
From: Xin Long <lucien.xin@gmail.com>
Date: Tue, 8 Aug 2017 15:25:25 +0800
> Now xt_tgchk_param par in ipt_init_target is a local varibale,
> par.net is not initialized there. Later when xt_check_target
> calls target's checkentry in which it may access par.net, it
> would cause kernel panic.
>
> Jaroslav found this panic when running:
>
> # ip link add TestIface type dummy
> # tc qd add dev TestIface ingress handle ffff:
> # tc filter add dev TestIface parent ffff: u32 match u32 0 0 \
> action xt -j CONNMARK --set-mark 4
>
> This patch is to pass net param into ipt_init_target and set
> par.net with it properly in there.
>
> v1->v2:
> As Wang Cong pointed, I missed ipt_net_id != xt_net_id, so fix
> it by also passing net_id to __tcf_ipt_init.
> v2->v3:
> Missed the fixes tag, so add it.
>
> Fixes: ecb2421b5ddf ("netfilter: add and use nf_ct_netns_get/put")
> Reported-by: Jaroslav Aster <jaster@redhat.com>
> Signed-off-by: Xin Long <lucien.xin@gmail.com>
Applied and queued up for -stable, thanks.
^ permalink raw reply
* [PATCH iproute2 master] examples/bpf: update list of examples
From: Alexander Alemayhu @ 2017-08-09 3:39 UTC (permalink / raw)
To: netdev; +Cc: stephen, Alexander Alemayhu
Remove deleted examples and add the new map in map example.
Signed-off-by: Alexander Alemayhu <alexander@alemayhu.com>
---
examples/bpf/README | 7 +------
1 file changed, 1 insertion(+), 6 deletions(-)
diff --git a/examples/bpf/README b/examples/bpf/README
index 4247257850eb..1bbdda3f8dc1 100644
--- a/examples/bpf/README
+++ b/examples/bpf/README
@@ -1,13 +1,8 @@
eBPF toy code examples (running in kernel) to familiarize yourself
with syntax and features:
- - bpf_prog.c -> Classifier examples with using maps
- bpf_shared.c -> Ingress/egress map sharing example
- bpf_tailcall.c -> Using tail call chains
- bpf_cyclic.c -> Simple cycle as tail calls
- bpf_graft.c -> Demo on altering runtime behaviour
-
-User space code example:
-
- - bpf_agent.c -> Counterpart to bpf_prog.c for user
- space to transfer/read out map data
+ - bpf_map_in_map.c -> Using map in map example
--
2.13.3
^ permalink raw reply related
* Re: [PATCH net] tcp: fastopen: tcp_connect() must refresh the route
From: David Miller @ 2017-08-09 4:04 UTC (permalink / raw)
To: eric.dumazet; +Cc: netdev, weiwan, ycheng, dvyukov
In-Reply-To: <1502181718.4487.9.camel@edumazet-glaptop3.roam.corp.google.com>
From: Eric Dumazet <eric.dumazet@gmail.com>
Date: Tue, 08 Aug 2017 01:41:58 -0700
> From: Eric Dumazet <edumazet@google.com>
>
> With new TCP_FASTOPEN_CONNECT socket option, there is a possibility
> to call tcp_connect() while socket sk_dst_cache is either NULL
> or invalid.
>
> +0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 4
> +0 fcntl(4, F_SETFL, O_RDWR|O_NONBLOCK) = 0
> +0 setsockopt(4, SOL_TCP, TCP_FASTOPEN_CONNECT, [1], 4) = 0
> +0 connect(4, ..., ...) = 0
>
> << sk->sk_dst_cache becomes obsolete, or even set to NULL >>
>
> +1 sendto(4, ..., 1000, MSG_FASTOPEN, ..., ...) = 1000
>
>
> We need to refresh the route otherwise bad things can happen,
> especially when syzkaller is running on the host :/
>
> Fixes: 19f6d3f3c8422 ("net/tcp-fastopen: Add new API support")
> Reported-by: Dmitry Vyukov <dvyukov@google.com>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
Applied and queued up for -stable.
^ permalink raw reply
* Re: [PATCH net] rds: Reintroduce statistics counting
From: David Miller @ 2017-08-09 4:04 UTC (permalink / raw)
To: Haakon.Bugge
Cc: santosh.shilimkar, netdev, linux-rdma, rds-devel, linux-kernel,
knut.omang, wei.lin-guay
In-Reply-To: <20170808091332.5413-1-Haakon.Bugge@oracle.com>
From: Håkon Bugge <Haakon.Bugge@oracle.com>
Date: Tue, 8 Aug 2017 11:13:32 +0200
> In commit 7e3f2952eeb1 ("rds: don't let RDS shutdown a connection
> while senders are present"), refilling the receive queue was removed
> from rds_ib_recv(), along with the increment of
> s_ib_rx_refill_from_thread.
>
> Commit 73ce4317bf98 ("RDS: make sure we post recv buffers")
> re-introduces filling the receive queue from rds_ib_recv(), but does
> not add the statistics counter. rds_ib_recv() was later renamed to
> rds_ib_recv_path().
>
> This commit reintroduces the statistics counting of
> s_ib_rx_refill_from_thread and s_ib_rx_refill_from_cq.
>
> Signed-off-by: Håkon Bugge <haakon.bugge@oracle.com>
> Reviewed-by: Knut Omang <knut.omang@oracle.com>
> Reviewed-by: Wei Lin Guay <wei.lin.guay@oracle.com>
Applied.
^ permalink raw reply
* Re: [PATCH] net: phy: Use tab for indentation in Kconfig
From: David Miller @ 2017-08-09 4:05 UTC (permalink / raw)
To: michal.simek; +Cc: linux-kernel, monstr, netdev, andrew, f.fainelli
In-Reply-To: <abacdc7ec0585cfbeba240ca2780c6020cf7090a.1502184742.git.michal.simek@xilinx.com>
From: Michal Simek <michal.simek@xilinx.com>
Date: Tue, 8 Aug 2017 11:32:25 +0200
> Using tabs instead of space for indentaion
>
> Signed-off-by: Michal Simek <michal.simek@xilinx.com>
This really isn't appropriate for the 'net' tree, it doesn't fix
anything it just makes the spacing consistent.
Please respin this patch against net-next, thank you.
^ permalink raw reply
* Re: [PATCH net] ppp: fix xmit recursion detection on ppp channels
From: David Miller @ 2017-08-09 4:07 UTC (permalink / raw)
To: g.nault; +Cc: netdev, gfree.wind, jianying.liu, linux-ppp, paulus
In-Reply-To: <e45ed6ea02e2665ec8b868279ad9afcb9b34fc81.1502185216.git.g.nault@alphalink.fr>
From: Guillaume Nault <g.nault@alphalink.fr>
Date: Tue, 8 Aug 2017 11:43:24 +0200
> Commit e5dadc65f9e0 ("ppp: Fix false xmit recursion detect with two ppp
> devices") dropped the xmit_recursion counter incrementation in
> ppp_channel_push() and relied on ppp_xmit_process() for this task.
> But __ppp_channel_push() can also send packets directly (using the
> .start_xmit() channel callback), in which case the xmit_recursion
> counter isn't incremented anymore. If such packets get routed back to
> the parent ppp unit, ppp_xmit_process() won't notice the recursion and
> will call ppp_channel_push() on the same channel, effectively creating
> the deadlock situation that the xmit_recursion mechanism was supposed
> to prevent.
>
> This patch re-introduces the xmit_recursion counter incrementation in
> ppp_channel_push(). Since the xmit_recursion variable is now part of
> the parent ppp unit, incrementation is skipped if the channel doesn't
> have any. This is fine because only packets routed through the parent
> unit may enter the channel recursively.
>
> Finally, we have to ensure that pch->ppp is not going to be modified
> while executing ppp_channel_push(). Instead of taking this lock only
> while calling ppp_xmit_process(), we now have to hold it for the full
> ppp_channel_push() execution. This respects the ppp locks ordering
> which requires locking ->upl before ->downl.
>
> Fixes: e5dadc65f9e0 ("ppp: Fix false xmit recursion detect with two ppp devices")
> Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>
Applied, thank you.
^ permalink raw reply
* Re: [PATCH][next] net: phy: mdio-bcm-unimac: fix unsigned wrap-around when decrementing timeout
From: David Miller @ 2017-08-09 4:07 UTC (permalink / raw)
To: colin.king; +Cc: andrew, f.fainelli, netdev, kernel-janitors, linux-kernel
In-Reply-To: <20170808095232.13490-1-colin.king@canonical.com>
From: Colin King <colin.king@canonical.com>
Date: Tue, 8 Aug 2017 10:52:32 +0100
> From: Colin Ian King <colin.king@canonical.com>
>
> Change post-decrement compare to pre-decrement to avoid an
> unsigned integer wrap-around on timeout. This leads to the following
> !timeout check to never to be true so -ETIMEDOUT is never returned.
>
> Detected by CoverityScan, CID#1452623 ("Logically dead code")
>
> Fixes: 69a60b0579a4 ("net: phy: mdio-bcm-unimac: factor busy polling loop")
> Signed-off-by: Colin Ian King <colin.king@canonical.com>
Applied.
^ permalink raw reply
* Re: [PATCH 33/35] wireless: realtek: rtl8192cu: constify usb_device_id
From: Larry Finger @ 2017-08-09 4:09 UTC (permalink / raw)
To: Arvind Yadav, kvalo, chaoming_li; +Cc: linux-kernel, netdev, linux-wireless
In-Reply-To: <1502208353-12447-1-git-send-email-arvind.yadav.cs@gmail.com>
On 08/08/2017 11:05 AM, Arvind Yadav wrote:
> usb_device_id are not supposed to change at runtime. All functions
> working with usb_device_id provided by <linux/usb.h> work with
> const usb_device_id. So mark the non-const structs as const.
>
> Signed-off-by: Arvind Yadav <arvind.yadav.cs@gmail.com>
> ---
Acked-by: Larry Finger <Larry.Finger@lwfinger.net>
Thanks,
Larry
> drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c
> index 96c923b..e673bc2 100644
> --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c
> +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192cu/sw.c
> @@ -275,7 +275,7 @@ static struct rtl_hal_cfg rtl92cu_hal_cfg = {
> #define USB_VENDER_ID_REALTEK 0x0bda
>
> /* 2010-10-19 DID_USB_V3.4 */
> -static struct usb_device_id rtl8192c_usb_ids[] = {
> +static const struct usb_device_id rtl8192c_usb_ids[] = {
>
> /*=== Realtek demoboard ===*/
> /* Default ID */
>
^ permalink raw reply
* Re: [PATCH] hv_set_ifconfig.sh double check before setting ip
From: David Miller @ 2017-08-09 4:11 UTC (permalink / raw)
To: otubo; +Cc: netdev, linux-kernel, devel, sthemmin, haiyangz, kys
In-Reply-To: <20170808135345.17027-1-otubo@redhat.com>
From: Eduardo Otubo <otubo@redhat.com>
Date: Tue, 8 Aug 2017 15:53:45 +0200
> This patch fixes the behavior of the hv_set_ifconfig script when setting
> the interface ip. Sometimes the interface has already been configured by
> network daemon, in this case hv_set_ifconfig causes "RTNETLINK: file
> exists error"; in order to avoid this error this patch makes sure double
> checks the interface before trying anything.
>
> Signed-off-by: Eduardo Otubo <otubo@redhat.com>
And if the daemon sets the address after you test it but before
you try to set it in the script, what happens?
This is why I hate changes like this. They don't remove the problem,
they make it smaller. And smaller in a bad way. Smaller makes the
problem even more harder to diagnose when it happens.
There is implicitly no synchonization between network configuration
daemons and things people run by hand like this script.
So, caveat emptor.
I'm not applying this, sorry.
^ permalink raw reply
* Re: [PATCH net,stable] qmi_wwan: fix NULL deref on disconnect
From: David Miller @ 2017-08-09 4:14 UTC (permalink / raw)
To: bjorn; +Cc: netdev, linux-usb, dnlplm
In-Reply-To: <20170808160211.4777-1-bjorn@mork.no>
From: Bjørn Mork <bjorn@mork.no>
Date: Tue, 8 Aug 2017 18:02:11 +0200
> qmi_wwan_disconnect is called twice when disconnecting devices with
> separate control and data interfaces. The first invocation will set
> the interface data to NULL for both interfaces to flag that the
> disconnect has been handled. But the matching NULL check was left
> out when qmi_wwan_disconnect was added, resulting in this oops:
>
> usb 2-1.4: USB disconnect, device number 4
> qmi_wwan 2-1.4:1.6 wwp0s29u1u4i6: unregister 'qmi_wwan' usb-0000:00:1d.0-1.4, WWAN/QMI device
> BUG: unable to handle kernel NULL pointer dereference at 00000000000000e0
> IP: qmi_wwan_disconnect+0x25/0xc0 [qmi_wwan]
> PGD 0
> P4D 0
> Oops: 0000 [#1] SMP
> Modules linked in: <stripped irrelevant module list>
> CPU: 2 PID: 33 Comm: kworker/2:1 Tainted: G E 4.12.3-nr44-normandy-r1500619820+ #1
> Hardware name: LENOVO 4291LR7/4291LR7, BIOS CBET4000 4.6-810-g50522254fb 07/21/2017
> Workqueue: usb_hub_wq hub_event [usbcore]
> task: ffff8c882b716040 task.stack: ffffb8e800d84000
> RIP: 0010:qmi_wwan_disconnect+0x25/0xc0 [qmi_wwan]
> RSP: 0018:ffffb8e800d87b38 EFLAGS: 00010246
> RAX: 0000000000000000 RBX: 0000000000000000 RCX: 0000000000000000
> RDX: 0000000000000001 RSI: ffff8c8824f3f1d0 RDI: ffff8c8824ef6400
> RBP: ffff8c8824ef6400 R08: 0000000000000000 R09: 0000000000000000
> R10: ffffb8e800d87780 R11: 0000000000000011 R12: ffffffffc07ea0e8
> R13: ffff8c8824e2e000 R14: ffff8c8824e2e098 R15: 0000000000000000
> FS: 0000000000000000(0000) GS:ffff8c8835300000(0000) knlGS:0000000000000000
> CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> CR2: 00000000000000e0 CR3: 0000000229ca5000 CR4: 00000000000406e0
> Call Trace:
> ? usb_unbind_interface+0x71/0x270 [usbcore]
> ? device_release_driver_internal+0x154/0x210
> ? qmi_wwan_unbind+0x6d/0xc0 [qmi_wwan]
> ? usbnet_disconnect+0x6c/0xf0 [usbnet]
> ? qmi_wwan_disconnect+0x87/0xc0 [qmi_wwan]
> ? usb_unbind_interface+0x71/0x270 [usbcore]
> ? device_release_driver_internal+0x154/0x210
>
> Reported-and-tested-by: Nathaniel Roach <nroach44@gmail.com>
> Fixes: c6adf77953bc ("net: usb: qmi_wwan: add qmap mux protocol support")
> Cc: Daniele Palmas <dnlplm@gmail.com>
> Signed-off-by: Bjørn Mork <bjorn@mork.no>
Applied and queued up for -stable, thanks.
^ permalink raw reply
* Re: [PATCH net-next 0/7] rtnetlink: allow to run selected handlers without rtnl
From: David Miller @ 2017-08-09 4:33 UTC (permalink / raw)
To: fw; +Cc: netdev
In-Reply-To: <20170808160236.28562-1-fw@strlen.de>
From: Florian Westphal <fw@strlen.de>
Date: Tue, 8 Aug 2017 18:02:29 +0200
> Unfortunately RTNL mutex is a performance issue, e.g. a cpu adding
> an ip address prevents other cpus from seemingly unrelated tasks
> such as dumping tc classifiers.
It is related if somehow the TC entries refer to IP addresses.
Someone could create something like that.
> Initial no-rtnl spots are ip6 fib add/del and netns new/getid.
I could see the netns stuff being ok, but IPv6 route add/del I'm
not so sure of.
Because of things like nexthops etc. there are dependencies on
other configuration things.
That's the whole reason we have this unfortunate global
synchronization point. If I'm changing some aspect of network
configuration, I know I can atomically test any piece of networking
configuration state.
If I test a network address to make sure I can properly reacy X and
use X as a nexthop in the route I'm adding, it will be there
throughout the entire operation.
There really is a hierachy of these dependencies. Device state, up
to neighbour table state, up to protocol address state, up to routes,
up to FIB tables, etc. etc. etc.
I'd really like to make this operate more freely, but this is an
extremely delicate area which has been bottled up like this for
two decades so good luck :-)
^ permalink raw reply
* Re: [PATCH net] Revert "vhost: cache used event for better performance"
From: Michael S. Tsirkin @ 2017-08-09 4:37 UTC (permalink / raw)
To: Jason Wang; +Cc: netdev, linux-kernel, kvm, K. Den, virtualization
In-Reply-To: <6698b85c-18f4-17e6-db70-7708692fb761@redhat.com>
On Wed, Aug 09, 2017 at 10:38:10AM +0800, Jason Wang wrote:
> I think don't think current code can work well if vq.num is grater than
> 2^15. Since all cached idx is u16. This looks like a bug which needs to be
> fixed.
That's a limitation of virtio 1.0.
> > * else if the interval of vq.num is [2^15, 2^16):
> > the logic in the original patch (809ecb9bca6a9) suffices
> > * else (= less than 2^15) (optional):
> > checking only (vring_need_event(vq->last_used_event, new + vq->num, new)
> > would suffice.
> >
> > Am I missing something, or is this irrelevant?
Could you pls repost the suggestion copying virtio-dev mailing list
(subscriber only, sorry about that, but host/guest ABI discussions
need to copy that list)?
> Looks not, I think this may work. Let me do some test.
>
> Thanks
I think that at this point it's prudent to add a feature bit
as the virtio spec does not require to never move the event index back.
^ permalink raw reply
* Re: [PATCH net] net: avoid skb_warn_bad_offload false positives on UFO
From: David Miller @ 2017-08-09 4:39 UTC (permalink / raw)
To: willemdebruijn.kernel; +Cc: netdev, eric.dumazet, xiangxia.m.yue, willemb
In-Reply-To: <20170808182255.88431-1-willemdebruijn.kernel@gmail.com>
From: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
Date: Tue, 8 Aug 2017 14:22:55 -0400
> From: Willem de Bruijn <willemb@google.com>
>
> skb_warn_bad_offload triggers a warning when an skb enters the GSO
> stack at __skb_gso_segment that does not have CHECKSUM_PARTIAL
> checksum offload set.
>
> Commit b2504a5dbef3 ("net: reduce skb_warn_bad_offload() noise")
> observed that SKB_GSO_DODGY producers can trigger the check and
> that passing those packets through the GSO handlers will fix it
> up. But, the software UFO handler will set ip_summed to
> CHECKSUM_NONE.
>
> When __skb_gso_segment is called from the receive path, this
> triggers the warning again.
>
> Make UFO set CHECKSUM_UNNECESSARY instead of CHECKSUM_NONE. On
> Tx these two are equivalent. On Rx, this better matches the
> skb state (checksum computed), as CHECKSUM_NONE here means no
> checksum computed.
>
> See also this thread for context:
> http://patchwork.ozlabs.org/patch/799015/
>
> Fixes: b2504a5dbef3 ("net: reduce skb_warn_bad_offload() noise")
> Signed-off-by: Willem de Bruijn <willemb@google.com>
Applied and queued up for -stable, thank you.
^ permalink raw reply
* Re: [PATCH net-next v2] net: ipv6: avoid overhead when no custom FIB rules are installed
From: David Miller @ 2017-08-09 4:40 UTC (permalink / raw)
To: vincent; +Cc: kuznet, yoshfuji, jiri, netdev, dsa
In-Reply-To: <20170808182349.4987-1-vincent@bernat.im>
From: Vincent Bernat <vincent@bernat.im>
Date: Tue, 8 Aug 2017 20:23:49 +0200
> If the user hasn't installed any custom rules, don't go through the
> whole FIB rules layer. This is pretty similar to f4530fa574df (ipv4:
> Avoid overhead when no custom FIB rules are installed).
>
> Using a micro-benchmark module [1], timing ip6_route_output() with
> get_cycles(), with 40,000 routes in the main routing table, before this
> patch:
>
> min=606 max=12911 count=627 average=1959 95th=4903 90th=3747 50th=1602 mad=821
> table=254 avgdepth=21.8 maxdepth=39
> value │ ┊ count
> 600 │▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ 199
> 880 │▒▒▒░░░░░░░░░░░░░░░░ 43
> 1160 │▒▒▒░░░░░░░░░░░░░░░░░░░░ 48
> 1440 │▒▒▒░░░░░░░░░░░░░░░░░░░░░░░ 43
> 1720 │▒▒▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░ 59
> 2000 │▒▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 50
> 2280 │▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 26
> 2560 │▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 31
> 2840 │▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 28
> 3120 │▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 17
> 3400 │▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 17
> 3680 │░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 8
> 3960 │░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 11
> 4240 │░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 6
> 4520 │░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 6
> 4800 │░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 9
>
> After:
>
> min=544 max=11687 count=627 average=1776 95th=4546 90th=3585 50th=1227 mad=565
> table=254 avgdepth=21.8 maxdepth=39
> value │ ┊ count
> 540 │▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒ 201
> 800 │▒▒▒▒▒░░░░░░░░░░░░░░░░ 63
> 1060 │▒▒▒▒▒░░░░░░░░░░░░░░░░░░░░░ 68
> 1320 │▒▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░ 39
> 1580 │▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 32
> 1840 │▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 32
> 2100 │▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 34
> 2360 │▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 33
> 2620 │▒▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 26
> 2880 │▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 22
> 3140 │░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 9
> 3400 │░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 8
> 3660 │░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 9
> 3920 │░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 8
> 4180 │░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 8
> 4440 │░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 8
>
> At the frequency of the host during the bench (~ 3.7 GHz), this is
> about a 100 ns difference on the median value.
>
> A next step would be to collapse local and main tables, as in
> 0ddcf43d5d4a (ipv4: FIB Local/MAIN table collapse).
>
> [1]: https://github.com/vincentbernat/network-lab/blob/master/lab-routes-ipv6/kbench_mod.c
>
> Signed-off-by: Vincent Bernat <vincent@bernat.im>
> Reviewed-by: Jiri Pirko <jiri@mellanox.com>
Looks great, applied, thanks!
^ permalink raw reply
* Re: panic at sock_zerocopy_put when I ssh into a VM
From: Willem de Bruijn @ 2017-08-09 4:48 UTC (permalink / raw)
To: David Ahern; +Cc: Willem de Bruijn, netdev@vger.kernel.org
In-Reply-To: <9ea97b60-7416-bdb2-e167-8fcc8c11b1cc@gmail.com>
Thanks for the report, David, and sorry for the breakage.
I am not able to reproduce the issue with my qemu setup with vhost-net
with experimental_zcopytx so far.
But looking at the code from that codepath point of view, I do see
that there are incorrect assumptions on ubuf_info fields being
initialized anytime skb_zcopy(skb) is true, that are not true for the
legacy zerocopy case.
Specifically, uarg->mmp and uarg->zerocopy are only valid for
msg_zerocopy. The first can conceivably result in dereferencing
a garbage pointer if an ubuf_info from vhost is passed that does
not have this field properly initialized.
I will take a deeper look. As a first attempt, the following may fix
the issue for this vhost case (only):
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index ba08b78ed630..e1e96d97de71 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -253,7 +253,7 @@ static int vhost_net_set_ubuf_info(struct vhost_net *n)
zcopy = vhost_net_zcopy_mask & (0x1 << i);
if (!zcopy)
continue;
- n->vqs[i].ubuf_info = kmalloc(sizeof(*n->vqs[i].ubuf_info) *
+ n->vqs[i].ubuf_info = kzalloc(sizeof(*n->vqs[i].ubuf_info) *
UIO_MAXIOV, GFP_KERNEL);
if (!n->vqs[i].ubuf_info)
goto err;
Less critical is correctly returning whether the operation completed
without resorting to copying. Boolean uarg->zerocopy is undefined.
This should not cause a kernel panic, as the vhost driver must handle
both cases safely.
Only msg_zerocopy sets bot SKBTX_ZEROCOPY_FRAG and
SKBTX_DEV_ZEROCOPY, which is one way to identify this
special case.
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 8c0708d2e5e6..7fb8b11ba8f6 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -1273,7 +1273,10 @@ static inline void skb_zcopy_clear(struct
sk_buff *skb, bool zerocopy)
struct ubuf_info *uarg = skb_zcopy(skb);
if (uarg) {
- uarg->zerocopy = uarg->zerocopy && zerocopy;
+ if (skb_shinfo(skb)->tx_flags & SKBTX_SHARED_FRAG)
+ uarg->zerocopy = uarg->zerocopy && zerocopy;
+ else
+ uarg->zerocopy = zerocopy;
sock_zerocopy_put(uarg);
skb_shinfo(skb)->tx_flags &= ~SKBTX_ZEROCOPY_FRAG;
}
On Tue, Aug 8, 2017 at 6:14 PM, David Ahern <dsahern@gmail.com> wrote:
> Willem:
>
> I updated my host server this morning to top of net-next -- commit
> 53b948356554. I am not doing anything fancy or intentionally using the
> zerocopy code. I launch a VM with vhost and attempt to login via ssh.
> Doing that triggers a panic in the host at sock_zerocopy_put. The
> attached is a snapshot of the console -- best I can get for the stack trace.
>
> David
^ permalink raw reply related
* Re: panic at sock_zerocopy_put when I ssh into a VM
From: Willem de Bruijn @ 2017-08-09 5:01 UTC (permalink / raw)
To: David Ahern; +Cc: Willem de Bruijn, netdev@vger.kernel.org
In-Reply-To: <CAF=yD-J8JMyVq3Qt2n+L-EmpxacJ=mD7-KdsjgO3YB3LAzbKMQ@mail.gmail.com>
On Tue, Aug 8, 2017 at 9:48 PM, Willem de Bruijn
<willemdebruijn.kernel@gmail.com> wrote:
> Thanks for the report, David, and sorry for the breakage.
>
> I am not able to reproduce the issue with my qemu setup with vhost-net
> with experimental_zcopytx so far.
I did just reproduce the (well, a) panic in sock_zerocopy_put. It is
indeed in the mm_unaccount_pinned_pages code that tests
uarg->mmp:
(gdb) list *(sock_zerocopy_put+0x26)
0xffffffff81620316 is in sock_zerocopy_put (net/core/skbuff.c:933).
928 }
929
930 static void mm_unaccount_pinned_pages(struct mmpin *mmp)
931 {
932 if (mmp->user) {
933 atomic_long_sub(mmp->num_pg, &mmp->user->locked_vm);
934 free_uid(mmp->user);
This gives me more confidence that the previous fix is sufficient.
I will have to revise it to avoid this path for all zerocopy paths
besides msg_zerocopy.
^ permalink raw reply
* [PATCH] net: dsa: make dsa_switch_ops const
From: Bhumika Goyal @ 2017-08-09 5:04 UTC (permalink / raw)
To: julia.lawall, andrew, vivien.didelot, f.fainelli, netdev,
linux-kernel
Cc: Bhumika Goyal
Make these structures const as they are only stored in the ops field of
a dsa_switch structure, which is const.
Done using Coccinelle.
Signed-off-by: Bhumika Goyal <bhumirks@gmail.com>
---
drivers/net/dsa/dsa_loop.c | 2 +-
drivers/net/dsa/lan9303-core.c | 2 +-
drivers/net/dsa/mt7530.c | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/dsa/dsa_loop.c b/drivers/net/dsa/dsa_loop.c
index 76d6660..7819a9f 100644
--- a/drivers/net/dsa/dsa_loop.c
+++ b/drivers/net/dsa/dsa_loop.c
@@ -257,7 +257,7 @@ static int dsa_loop_port_vlan_del(struct dsa_switch *ds, int port,
return 0;
}
-static struct dsa_switch_ops dsa_loop_driver = {
+static const struct dsa_switch_ops dsa_loop_driver = {
.get_tag_protocol = dsa_loop_get_protocol,
.setup = dsa_loop_setup,
.get_strings = dsa_loop_get_strings,
diff --git a/drivers/net/dsa/lan9303-core.c b/drivers/net/dsa/lan9303-core.c
index 15befd1..f058f98 100644
--- a/drivers/net/dsa/lan9303-core.c
+++ b/drivers/net/dsa/lan9303-core.c
@@ -797,7 +797,7 @@ static void lan9303_port_disable(struct dsa_switch *ds, int port,
}
}
-static struct dsa_switch_ops lan9303_switch_ops = {
+static const struct dsa_switch_ops lan9303_switch_ops = {
.get_tag_protocol = lan9303_get_tag_protocol,
.setup = lan9303_setup,
.get_strings = lan9303_get_strings,
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 1270071..7d8cf927 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -979,7 +979,7 @@ static void mt7530_adjust_link(struct dsa_switch *ds, int port,
return 0;
}
-static struct dsa_switch_ops mt7530_switch_ops = {
+static const struct dsa_switch_ops mt7530_switch_ops = {
.get_tag_protocol = mtk_get_tag_protocol,
.setup = mt7530_setup,
.get_strings = mt7530_get_strings,
--
1.9.1
^ permalink raw reply related
* Re:Re: Re:Re: Re: [PATCH net] ppp: Fix a scheduling-while-atomic bug in del_chan
From: Gao Feng @ 2017-08-09 5:13 UTC (permalink / raw)
To: Cong Wang; +Cc: xeb, David Miller, Linux Kernel Network Developers
In-Reply-To: <CAM_iQpW8W24=2atSyStwKPYJ9zmOO5XiznktT3V_3qn00R7r=Q@mail.gmail.com>
At 2017-08-09 03:45:53, "Cong Wang" <xiyou.wangcong@gmail.com> wrote:
>On Mon, Aug 7, 2017 at 6:10 PM, Gao Feng <gfree.wind@vip.163.com> wrote:
>>
>> Sorry, I don't get you clearly. Why the sock_hold() isn't helpful?
>
>I already told you, the dereference happends before sock_hold().
>
> sock = rcu_dereference(callid_sock[call_id]);
> if (sock) {
> opt = &sock->proto.pptp;
> if (opt->dst_addr.sin_addr.s_addr != s_addr) <=== HERE
> sock = NULL;
> else
> sock_hold(sk_pppox(sock));
> }
>
>If we don't wait for readers properly, sock could be freed at the
>same time when deference it.
Maybe I didn't show my explanation clearly.
I think it won't happen as I mentioned in the last email.
Because the pptp_release invokes the synchronize_rcu to make sure it, and actually there is no one which would invoke del_chan except pptp_release.
It is guaranteed by that the pptp_release doesn't put the sock refcnt until complete all cleanup include marking sk_state as PPPOX_DEAD.
In other words, even though the pptp_release is not the last user of this sock, the other one wouldn't invoke del_chan in pptp_sock_destruct.
Because the condition "!(sk->sk_state & PPPOX_DEAD)" must be false.
As summary, the del_chan and pppox_unbind_sock in pptp_sock_destruct are unnecessary.
And it even brings confusing.
Best Regards
Feng
>
>> The pptp_release invokes synchronize_rcu after del_chan, it could make sure the others has increased the sock refcnt if necessary
>> and the lookup is over.
>> There is no one could get the sock after synchronize_rcu in pptp_release.
>
>
>If this were true, then this code in pptp_sock_destruct()
>would be unneeded:
>
> if (!(sk->sk_state & PPPOX_DEAD)) {
> del_chan(pppox_sk(sk));
> pppox_unbind_sock(sk);
> }
>
>
>>
>>
>> But I think about another problem.
>> It seems the pptp_sock_destruct should not invoke del_chan and pppox_unbind_sock.
>> Because when the sock refcnt is 0, the pptp_release must have be invoked already.
>>
>
>
>I don't know. Looks like sock_orphan() is only called
>in pptp_release(), but I am not sure if there is a case
>we call sock destructor before release.
>
>Also note, this socket is very special, it doesn't support
>poll(), sendmsg() or recvmsg()..
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox