353
#define TASKSTATS_NEEDS_PADDING 1
352
356
static struct taskstats *mk_reply(struct sk_buff *skb, int type, u32 pid)
354
358
struct nlattr *na, *ret;
357
/* If we don't pad, we end up with alignment on a 4 byte boundary.
358
* This causes lots of runtime warnings on systems requiring 8 byte
360
u32 pids[2] = { pid, 0 };
361
int pid_size = ALIGN(sizeof(pid), sizeof(long));
363
361
aggr = (type == TASKSTATS_TYPE_PID)
364
362
? TASKSTATS_TYPE_AGGR_PID
365
363
: TASKSTATS_TYPE_AGGR_TGID;
366
* The taskstats structure is internally aligned on 8 byte
367
* boundaries but the layout of the aggregrate reply, with
368
* two NLA headers and the pid (each 4 bytes), actually
369
* force the entire structure to be unaligned. This causes
370
* the kernel to issue unaligned access warnings on some
371
* architectures like ia64. Unfortunately, some software out there
372
* doesn't properly unroll the NLA packet and assumes that the start
373
* of the taskstats structure will always be 20 bytes from the start
374
* of the netlink payload. Aligning the start of the taskstats
375
* structure breaks this software, which we don't want. So, for now
376
* the alignment only happens on architectures that require it
377
* and those users will have to update to fixed versions of those
378
* packages. Space is reserved in the packet only when needed.
379
* This ifdef should be removed in several years e.g. 2012 once
380
* we can be confident that fixed versions are installed on most
381
* systems. We add the padding before the aggregate since the
382
* aggregate is already a defined type.
384
#ifdef TASKSTATS_NEEDS_PADDING
385
if (nla_put(skb, TASKSTATS_TYPE_NULL, 0, NULL) < 0)
367
388
na = nla_nest_start(skb, aggr);
370
if (nla_put(skb, type, pid_size, pids) < 0)
392
if (nla_put(skb, type, sizeof(pid), &pid) < 0)
372
394
ret = nla_reserve(skb, TASKSTATS_TYPE_STATS, sizeof(struct taskstats));
481
static size_t taskstats_packet_size(void)
485
size = nla_total_size(sizeof(u32)) +
486
nla_total_size(sizeof(struct taskstats)) + nla_total_size(0);
487
#ifdef TASKSTATS_NEEDS_PADDING
488
size += nla_total_size(0); /* Padding for alignment */
459
493
static int cmd_attr_pid(struct genl_info *info)
461
495
struct taskstats *stats;
467
size = nla_total_size(sizeof(u32)) +
468
nla_total_size(sizeof(struct taskstats)) + nla_total_size(0);
501
size = taskstats_packet_size();
470
503
rc = prepare_reply(info, TASKSTATS_CMD_NEW, &rep_skb, size);
497
size = nla_total_size(sizeof(u32)) +
498
nla_total_size(sizeof(struct taskstats)) + nla_total_size(0);
530
size = taskstats_packet_size();
500
532
rc = prepare_reply(info, TASKSTATS_CMD_NEW, &rep_skb, size);