Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 9966
b: refs/heads/master
c: c8f32be
h: refs/heads/master
v: v3
  • Loading branch information
Trond Myklebust authored and Trond Myklebust committed Oct 13, 2005
1 parent 0192ee1 commit 0ac9f82
Show file tree
Hide file tree
Showing 11 changed files with 120 additions and 33 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: 7217cbccbd0c620a6d234ebbe5e58d46d2188d0e
refs/heads/master: c8f32be3874a310fa963d47b534a98be1a05a4cc
44 changes: 44 additions & 0 deletions trunk/Documentation/connector/connector.txt
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,47 @@ Netlink itself is not reliable protocol, that means that messages can
be lost due to memory pressure or process' receiving queue overflowed,
so caller is warned must be prepared. That is why struct cn_msg [main
connector's message header] contains u32 seq and u32 ack fields.

/*****************************************/
Userspace usage.
/*****************************************/
2.6.14 has a new netlink socket implementation, which by default does not
allow to send data to netlink groups other than 1.
So, if to use netlink socket (for example using connector)
with different group number userspace application must subscribe to
that group. It can be achieved by following pseudocode:

s = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_CONNECTOR);

l_local.nl_family = AF_NETLINK;
l_local.nl_groups = 12345;
l_local.nl_pid = 0;

if (bind(s, (struct sockaddr *)&l_local, sizeof(struct sockaddr_nl)) == -1) {
perror("bind");
close(s);
return -1;
}

{
int on = l_local.nl_groups;
setsockopt(s, 270, 1, &on, sizeof(on));
}

Where 270 above is SOL_NETLINK, and 1 is a NETLINK_ADD_MEMBERSHIP socket
option. To drop multicast subscription one should call above socket option
with NETLINK_DROP_MEMBERSHIP parameter which is defined as 0.

2.6.14 netlink code only allows to select a group which is less or equal to
the maximum group number, which is used at netlink_kernel_create() time.
In case of connector it is CN_NETLINK_USERS + 0xf, so if you want to use
group number 12345, you must increment CN_NETLINK_USERS to that number.
Additional 0xf numbers are allocated to be used by non-in-kernel users.

Due to this limitation, group 0xffffffff does not work now, so one can
not use add/remove connector's group notifications, but as far as I know,
only cn_test.c test module used it.

Some work in netlink area is still being done, so things can be changed in
2.6.15 timeframe, if it will happen, documentation will be updated for that
kernel.
2 changes: 2 additions & 0 deletions trunk/arch/cris/arch-v32/kernel/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <linux/kernel.h>
#include <linux/cpumask.h>
#include <linux/interrupt.h>
#include <linux/module.h>

#define IPI_SCHEDULE 1
#define IPI_CALL 2
Expand All @@ -28,6 +29,7 @@ spinlock_t cris_atomic_locks[] = { [0 ... LOCK_COUNT - 1] = SPIN_LOCK_UNLOCKED};
/* CPU masks */
cpumask_t cpu_online_map = CPU_MASK_NONE;
cpumask_t phys_cpu_present_map = CPU_MASK_NONE;
EXPORT_SYMBOL(phys_cpu_present_map);

/* Variables used during SMP boot */
volatile int cpu_now_booting = 0;
Expand Down
3 changes: 3 additions & 0 deletions trunk/arch/sh/kernel/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <linux/time.h>
#include <linux/timex.h>
#include <linux/sched.h>
#include <linux/module.h>

#include <asm/atomic.h>
#include <asm/processor.h>
Expand All @@ -39,6 +40,8 @@ struct sh_cpuinfo cpu_data[NR_CPUS];
extern void per_cpu_trap_init(void);

cpumask_t cpu_possible_map;
EXPORT_SYMBOL(cpu_possible_map);

cpumask_t cpu_online_map;
static atomic_t cpus_booted = ATOMIC_INIT(0);

Expand Down
12 changes: 12 additions & 0 deletions trunk/include/linux/cpumask.h
Original file line number Diff line number Diff line change
Expand Up @@ -392,4 +392,16 @@ extern cpumask_t cpu_present_map;
#define for_each_online_cpu(cpu) for_each_cpu_mask((cpu), cpu_online_map)
#define for_each_present_cpu(cpu) for_each_cpu_mask((cpu), cpu_present_map)

/* Find the highest possible smp_processor_id() */
static inline unsigned int highest_possible_processor_id(void)
{
unsigned int cpu, highest = 0;

for_each_cpu_mask(cpu, cpu_possible_map)
highest = cpu;

return highest;
}


#endif /* __LINUX_CPUMASK_H */
27 changes: 17 additions & 10 deletions trunk/net/bridge/netfilter/ebtables.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <linux/spinlock.h>
#include <asm/uaccess.h>
#include <linux/smp.h>
#include <linux/cpumask.h>
#include <net/sock.h>
/* needed for logical [in,out]-dev filtering */
#include "../br_private.h"
Expand Down Expand Up @@ -823,10 +824,11 @@ static int translate_table(struct ebt_replace *repl,
/* this will get free'd in do_replace()/ebt_register_table()
if an error occurs */
newinfo->chainstack = (struct ebt_chainstack **)
vmalloc(num_possible_cpus() * sizeof(struct ebt_chainstack));
vmalloc((highest_possible_processor_id()+1)
* sizeof(struct ebt_chainstack));
if (!newinfo->chainstack)
return -ENOMEM;
for (i = 0; i < num_possible_cpus(); i++) {
for_each_cpu(i) {
newinfo->chainstack[i] =
vmalloc(udc_cnt * sizeof(struct ebt_chainstack));
if (!newinfo->chainstack[i]) {
Expand Down Expand Up @@ -895,9 +897,12 @@ static void get_counters(struct ebt_counter *oldcounters,

/* counters of cpu 0 */
memcpy(counters, oldcounters,
sizeof(struct ebt_counter) * nentries);
sizeof(struct ebt_counter) * nentries);

/* add other counters to those of cpu 0 */
for (cpu = 1; cpu < num_possible_cpus(); cpu++) {
for_each_cpu(cpu) {
if (cpu == 0)
continue;
counter_base = COUNTER_BASE(oldcounters, nentries, cpu);
for (i = 0; i < nentries; i++) {
counters[i].pcnt += counter_base[i].pcnt;
Expand Down Expand Up @@ -929,7 +934,8 @@ static int do_replace(void __user *user, unsigned int len)
BUGPRINT("Entries_size never zero\n");
return -EINVAL;
}
countersize = COUNTER_OFFSET(tmp.nentries) * num_possible_cpus();
countersize = COUNTER_OFFSET(tmp.nentries) *
(highest_possible_processor_id()+1);
newinfo = (struct ebt_table_info *)
vmalloc(sizeof(struct ebt_table_info) + countersize);
if (!newinfo)
Expand Down Expand Up @@ -1022,7 +1028,7 @@ static int do_replace(void __user *user, unsigned int len)

vfree(table->entries);
if (table->chainstack) {
for (i = 0; i < num_possible_cpus(); i++)
for_each_cpu(i)
vfree(table->chainstack[i]);
vfree(table->chainstack);
}
Expand All @@ -1040,7 +1046,7 @@ static int do_replace(void __user *user, unsigned int len)
vfree(counterstmp);
/* can be initialized in translate_table() */
if (newinfo->chainstack) {
for (i = 0; i < num_possible_cpus(); i++)
for_each_cpu(i)
vfree(newinfo->chainstack[i]);
vfree(newinfo->chainstack);
}
Expand Down Expand Up @@ -1132,7 +1138,8 @@ int ebt_register_table(struct ebt_table *table)
return -EINVAL;
}

countersize = COUNTER_OFFSET(table->table->nentries) * num_possible_cpus();
countersize = COUNTER_OFFSET(table->table->nentries) *
(highest_possible_processor_id()+1);
newinfo = (struct ebt_table_info *)
vmalloc(sizeof(struct ebt_table_info) + countersize);
ret = -ENOMEM;
Expand Down Expand Up @@ -1186,7 +1193,7 @@ int ebt_register_table(struct ebt_table *table)
up(&ebt_mutex);
free_chainstack:
if (newinfo->chainstack) {
for (i = 0; i < num_possible_cpus(); i++)
for_each_cpu(i)
vfree(newinfo->chainstack[i]);
vfree(newinfo->chainstack);
}
Expand All @@ -1209,7 +1216,7 @@ void ebt_unregister_table(struct ebt_table *table)
up(&ebt_mutex);
vfree(table->private->entries);
if (table->private->chainstack) {
for (i = 0; i < num_possible_cpus(); i++)
for_each_cpu(i)
vfree(table->private->chainstack[i]);
vfree(table->private->chainstack);
}
Expand Down
14 changes: 9 additions & 5 deletions trunk/net/ipv4/netfilter/arp_tables.c
Original file line number Diff line number Diff line change
Expand Up @@ -716,8 +716,10 @@ static int translate_table(const char *name,
}

/* And one copy for every other CPU */
for (i = 1; i < num_possible_cpus(); i++) {
memcpy(newinfo->entries + SMP_ALIGN(newinfo->size)*i,
for_each_cpu(i) {
if (i == 0)
continue;
memcpy(newinfo->entries + SMP_ALIGN(newinfo->size) * i,
newinfo->entries,
SMP_ALIGN(newinfo->size));
}
Expand Down Expand Up @@ -767,7 +769,7 @@ static void get_counters(const struct arpt_table_info *t,
unsigned int cpu;
unsigned int i;

for (cpu = 0; cpu < num_possible_cpus(); cpu++) {
for_each_cpu(cpu) {
i = 0;
ARPT_ENTRY_ITERATE(t->entries + TABLE_OFFSET(t, cpu),
t->size,
Expand Down Expand Up @@ -885,7 +887,8 @@ static int do_replace(void __user *user, unsigned int len)
return -ENOMEM;

newinfo = vmalloc(sizeof(struct arpt_table_info)
+ SMP_ALIGN(tmp.size) * num_possible_cpus());
+ SMP_ALIGN(tmp.size) *
(highest_possible_processor_id()+1));
if (!newinfo)
return -ENOMEM;

Expand Down Expand Up @@ -1158,7 +1161,8 @@ int arpt_register_table(struct arpt_table *table,
= { 0, 0, 0, { 0 }, { 0 }, { } };

newinfo = vmalloc(sizeof(struct arpt_table_info)
+ SMP_ALIGN(repl->size) * num_possible_cpus());
+ SMP_ALIGN(repl->size) *
(highest_possible_processor_id()+1));
if (!newinfo) {
ret = -ENOMEM;
return ret;
Expand Down
17 changes: 11 additions & 6 deletions trunk/net/ipv4/netfilter/ip_tables.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <asm/semaphore.h>
#include <linux/proc_fs.h>
#include <linux/err.h>
#include <linux/cpumask.h>

#include <linux/netfilter_ipv4/ip_tables.h>

Expand Down Expand Up @@ -921,8 +922,10 @@ translate_table(const char *name,
}

/* And one copy for every other CPU */
for (i = 1; i < num_possible_cpus(); i++) {
memcpy(newinfo->entries + SMP_ALIGN(newinfo->size)*i,
for_each_cpu(i) {
if (i == 0)
continue;
memcpy(newinfo->entries + SMP_ALIGN(newinfo->size) * i,
newinfo->entries,
SMP_ALIGN(newinfo->size));
}
Expand All @@ -943,7 +946,7 @@ replace_table(struct ipt_table *table,
struct ipt_entry *table_base;
unsigned int i;

for (i = 0; i < num_possible_cpus(); i++) {
for_each_cpu(i) {
table_base =
(void *)newinfo->entries
+ TABLE_OFFSET(newinfo, i);
Expand Down Expand Up @@ -990,7 +993,7 @@ get_counters(const struct ipt_table_info *t,
unsigned int cpu;
unsigned int i;

for (cpu = 0; cpu < num_possible_cpus(); cpu++) {
for_each_cpu(cpu) {
i = 0;
IPT_ENTRY_ITERATE(t->entries + TABLE_OFFSET(t, cpu),
t->size,
Expand Down Expand Up @@ -1128,7 +1131,8 @@ do_replace(void __user *user, unsigned int len)
return -ENOMEM;

newinfo = vmalloc(sizeof(struct ipt_table_info)
+ SMP_ALIGN(tmp.size) * num_possible_cpus());
+ SMP_ALIGN(tmp.size) *
(highest_possible_processor_id()+1));
if (!newinfo)
return -ENOMEM;

Expand Down Expand Up @@ -1458,7 +1462,8 @@ int ipt_register_table(struct ipt_table *table, const struct ipt_replace *repl)
= { 0, 0, 0, { 0 }, { 0 }, { } };

newinfo = vmalloc(sizeof(struct ipt_table_info)
+ SMP_ALIGN(repl->size) * num_possible_cpus());
+ SMP_ALIGN(repl->size) *
(highest_possible_processor_id()+1));
if (!newinfo)
return -ENOMEM;

Expand Down
12 changes: 7 additions & 5 deletions trunk/net/ipv4/tcp_output.c
Original file line number Diff line number Diff line change
Expand Up @@ -436,11 +436,13 @@ int tcp_fragment(struct sock *sk, struct sk_buff *skb, u32 len, unsigned int mss
u16 flags;

if (unlikely(len >= skb->len)) {
printk(KERN_DEBUG "TCP: seg_size=%u, mss=%u, seq=%u, "
"end_seq=%u, skb->len=%u.\n", len, mss_now,
TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq,
skb->len);
WARN_ON(1);
if (net_ratelimit()) {
printk(KERN_DEBUG "TCP: seg_size=%u, mss=%u, seq=%u, "
"end_seq=%u, skb->len=%u.\n", len, mss_now,
TCP_SKB_CB(skb)->seq, TCP_SKB_CB(skb)->end_seq,
skb->len);
WARN_ON(1);
}
return 0;
}

Expand Down
16 changes: 11 additions & 5 deletions trunk/net/ipv6/netfilter/ip6_tables.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <asm/uaccess.h>
#include <asm/semaphore.h>
#include <linux/proc_fs.h>
#include <linux/cpumask.h>

#include <linux/netfilter_ipv6/ip6_tables.h>

Expand Down Expand Up @@ -950,8 +951,10 @@ translate_table(const char *name,
}

/* And one copy for every other CPU */
for (i = 1; i < num_possible_cpus(); i++) {
memcpy(newinfo->entries + SMP_ALIGN(newinfo->size)*i,
for_each_cpu(i) {
if (i == 0)
continue;
memcpy(newinfo->entries + SMP_ALIGN(newinfo->size) * i,
newinfo->entries,
SMP_ALIGN(newinfo->size));
}
Expand All @@ -973,6 +976,7 @@ replace_table(struct ip6t_table *table,
unsigned int i;

for (i = 0; i < num_possible_cpus(); i++) {
for_each_cpu(i) {
table_base =
(void *)newinfo->entries
+ TABLE_OFFSET(newinfo, i);
Expand Down Expand Up @@ -1019,7 +1023,7 @@ get_counters(const struct ip6t_table_info *t,
unsigned int cpu;
unsigned int i;

for (cpu = 0; cpu < num_possible_cpus(); cpu++) {
for_each_cpu(cpu) {
i = 0;
IP6T_ENTRY_ITERATE(t->entries + TABLE_OFFSET(t, cpu),
t->size,
Expand Down Expand Up @@ -1153,7 +1157,8 @@ do_replace(void __user *user, unsigned int len)
return -ENOMEM;

newinfo = vmalloc(sizeof(struct ip6t_table_info)
+ SMP_ALIGN(tmp.size) * num_possible_cpus());
+ SMP_ALIGN(tmp.size) *
(highest_possible_processor_id()+1));
if (!newinfo)
return -ENOMEM;

Expand Down Expand Up @@ -1467,7 +1472,8 @@ int ip6t_register_table(struct ip6t_table *table,
= { 0, 0, 0, { 0 }, { 0 }, { } };

newinfo = vmalloc(sizeof(struct ip6t_table_info)
+ SMP_ALIGN(repl->size) * num_possible_cpus());
+ SMP_ALIGN(repl->size) *
(highest_possible_processor_id()+1));
if (!newinfo)
return -ENOMEM;

Expand Down
4 changes: 3 additions & 1 deletion trunk/net/sched/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,11 @@ config NET_SCH_CLK_GETTIMEOFDAY
Choose this if you need a high resolution clock source but can't use
the CPU's cycle counter.

# don't allow on SMP x86 because they can have unsynchronized TSCs.
# gettimeofday is a good alternative
config NET_SCH_CLK_CPU
bool "CPU cycle counter"
depends on X86_TSC || X86_64 || ALPHA || SPARC64 || PPC64 || IA64
depends on ((X86_TSC || X86_64) && !SMP) || ALPHA || SPARC64 || PPC64 || IA64
help
Say Y here if you want to use the CPU's cycle counter as clock source.
This is a cheap and high resolution clock source, but on some
Expand Down

0 comments on commit 0ac9f82

Please sign in to comment.