Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 223515
b: refs/heads/master
c: 4be2c95
h: refs/heads/master
i:
  223513: 992b61f
  223511: 5653950
v: v3
  • Loading branch information
Jeff Mahoney authored and Linus Torvalds committed Dec 23, 2010
1 parent 40d5f10 commit 3628ba0
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 15 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 4e06fd14d5fa78826397c891654a37e5a36ee827
refs/heads/master: 4be2c95d1f7706ca0e74499f2bd118e1cee19669
1 change: 1 addition & 0 deletions trunk/Documentation/accounting/getdelays.c
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,7 @@ int main(int argc, char *argv[])
default:
fprintf(stderr, "Unknown nla_type %d\n",
na->nla_type);
case TASKSTATS_TYPE_NULL:
break;
}
na = (struct nlattr *) (GENLMSG_DATA(&msg) + len);
Expand Down
3 changes: 2 additions & 1 deletion trunk/include/linux/taskstats.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
*/


#define TASKSTATS_VERSION 7
#define TASKSTATS_VERSION 8
#define TS_COMM_LEN 32 /* should be >= TASK_COMM_LEN
* in linux/sched.h */

Expand Down Expand Up @@ -188,6 +188,7 @@ enum {
TASKSTATS_TYPE_STATS, /* taskstats structure */
TASKSTATS_TYPE_AGGR_PID, /* contains pid + stats */
TASKSTATS_TYPE_AGGR_TGID, /* contains tgid + stats */
TASKSTATS_TYPE_NULL, /* contains nothing */
__TASKSTATS_TYPE_MAX,
};

Expand Down
57 changes: 44 additions & 13 deletions trunk/kernel/taskstats.c
Original file line number Diff line number Diff line change
Expand Up @@ -349,25 +349,47 @@ static int parse(struct nlattr *na, struct cpumask *mask)
return ret;
}

#ifdef CONFIG_IA64
#define TASKSTATS_NEEDS_PADDING 1
#endif

static struct taskstats *mk_reply(struct sk_buff *skb, int type, u32 pid)
{
struct nlattr *na, *ret;
int aggr;

/* If we don't pad, we end up with alignment on a 4 byte boundary.
* This causes lots of runtime warnings on systems requiring 8 byte
* alignment */
u32 pids[2] = { pid, 0 };
int pid_size = ALIGN(sizeof(pid), sizeof(long));

aggr = (type == TASKSTATS_TYPE_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;
if (nla_put(skb, type, pid_size, pids) < 0)

if (nla_put(skb, type, sizeof(pid), &pid) < 0)
goto err;
ret = nla_reserve(skb, TASKSTATS_TYPE_STATS, sizeof(struct taskstats));
if (!ret)
Expand Down Expand Up @@ -456,6 +478,18 @@ static int cmd_attr_deregister_cpumask(struct genl_info *info)
return rc;
}

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
return size;
}

static int cmd_attr_pid(struct genl_info *info)
{
struct taskstats *stats;
Expand All @@ -464,8 +498,7 @@ static int cmd_attr_pid(struct genl_info *info)
u32 pid;
int rc;

size = nla_total_size(sizeof(u32)) +
nla_total_size(sizeof(struct taskstats)) + nla_total_size(0);
size = taskstats_packet_size();

rc = prepare_reply(info, TASKSTATS_CMD_NEW, &rep_skb, size);
if (rc < 0)
Expand Down Expand Up @@ -494,8 +527,7 @@ static int cmd_attr_tgid(struct genl_info *info)
u32 tgid;
int rc;

size = nla_total_size(sizeof(u32)) +
nla_total_size(sizeof(struct taskstats)) + nla_total_size(0);
size = taskstats_packet_size();

rc = prepare_reply(info, TASKSTATS_CMD_NEW, &rep_skb, size);
if (rc < 0)
Expand Down Expand Up @@ -570,8 +602,7 @@ void taskstats_exit(struct task_struct *tsk, int group_dead)
/*
* Size includes space for nested attributes
*/
size = nla_total_size(sizeof(u32)) +
nla_total_size(sizeof(struct taskstats)) + nla_total_size(0);
size = taskstats_packet_size();

is_thread_group = !!taskstats_tgid_alloc(tsk);
if (is_thread_group) {
Expand Down

0 comments on commit 3628ba0

Please sign in to comment.