Skip to content

Commit

Permalink
taskstats: use the libnl API to align nlattr on 64-bit
Browse files Browse the repository at this point in the history
Goal of this patch is to use the new libnl API to align netlink attribute
when needed.
The layout of the netlink message will be a bit different after the patch,
because the padattr (TASKSTATS_TYPE_STATS) will be inside the nested
attribute instead of before it.

Signed-off-by: Nicolas Dichtel <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
NicolasDichtel authored and davem330 committed Apr 24, 2016
1 parent de95c4a commit 80df554
Showing 1 changed file with 5 additions and 32 deletions.
37 changes: 5 additions & 32 deletions kernel/taskstats.c
Original file line number Diff line number Diff line change
Expand Up @@ -357,10 +357,6 @@ static int parse(struct nlattr *na, struct cpumask *mask)
return ret;
}

#if defined(CONFIG_64BIT) && !defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)
#define TASKSTATS_NEEDS_PADDING 1
#endif

static struct taskstats *mk_reply(struct sk_buff *skb, int type, u32 pid)
{
struct nlattr *na, *ret;
Expand All @@ -370,29 +366,6 @@ static struct taskstats *mk_reply(struct sk_buff *skb, int type, u32 pid)
? TASKSTATS_TYPE_AGGR_PID
: TASKSTATS_TYPE_AGGR_TGID;

/*
* The taskstats structure is internally aligned on 8 byte
* boundaries but the layout of the aggregrate reply, with
* two NLA headers and the pid (each 4 bytes), actually
* force the entire structure to be unaligned. This causes
* the kernel to issue unaligned access warnings on some
* architectures like ia64. Unfortunately, some software out there
* doesn't properly unroll the NLA packet and assumes that the start
* of the taskstats structure will always be 20 bytes from the start
* of the netlink payload. Aligning the start of the taskstats
* structure breaks this software, which we don't want. So, for now
* the alignment only happens on architectures that require it
* and those users will have to update to fixed versions of those
* packages. Space is reserved in the packet only when needed.
* This ifdef should be removed in several years e.g. 2012 once
* we can be confident that fixed versions are installed on most
* systems. We add the padding before the aggregate since the
* aggregate is already a defined type.
*/
#ifdef TASKSTATS_NEEDS_PADDING
if (nla_put(skb, TASKSTATS_TYPE_NULL, 0, NULL) < 0)
goto err;
#endif
na = nla_nest_start(skb, aggr);
if (!na)
goto err;
Expand All @@ -401,7 +374,8 @@ static struct taskstats *mk_reply(struct sk_buff *skb, int type, u32 pid)
nla_nest_cancel(skb, na);
goto err;
}
ret = nla_reserve(skb, TASKSTATS_TYPE_STATS, sizeof(struct taskstats));
ret = nla_reserve_64bit(skb, TASKSTATS_TYPE_STATS,
sizeof(struct taskstats), TASKSTATS_TYPE_NULL);
if (!ret) {
nla_nest_cancel(skb, na);
goto err;
Expand Down Expand Up @@ -500,10 +474,9 @@ static size_t taskstats_packet_size(void)
size_t size;

size = nla_total_size(sizeof(u32)) +
nla_total_size(sizeof(struct taskstats)) + nla_total_size(0);
#ifdef TASKSTATS_NEEDS_PADDING
size += nla_total_size(0); /* Padding for alignment */
#endif
nla_total_size_64bit(sizeof(struct taskstats)) +
nla_total_size(0);

return size;
}

Expand Down

0 comments on commit 80df554

Please sign in to comment.