* Re: [PATCH] pktgen: fix crash with vlan and packet size less than 46
From: Nishank Trivedi (nistrive) @ 2012-09-12 23:33 UTC (permalink / raw)
To: Nishank Trivedi (nistrive), netdev@vger.kernel.org
Cc: Christian Benvenuti (benve)
In-Reply-To: <1347492769-32409-1-git-send-email-nistrive@cisco.com>
Alternatively, instead of checking for datalen this late, one can also
impose a condition that pkt_size input must be at least 64. Within module,
I see various values hard-coded for UDP over ethernet, but not sure why
pkt_size is not rounded off to 64.
Thanks,
Nishank
On 9/12/12 4:32 PM, "Nishank Trivedi (nistrive)" <nistrive@cisco.com>
wrote:
>If vlan option is being specified in the pktgen and packet size
>being requested is less than 46 bytes, despite being illogical
>request, pktgen should not crash the kernel.
>
>BUG: unable to handle kernel paging request at ffff88021fb82000
>Process kpktgend_0 (pid: 1184, threadinfo ffff880215f1a000, task
>ffff880218544530)
>Call Trace:
>[<ffffffffa0637cd2>] ? pktgen_finalize_skb+0x222/0x300 [pktgen]
>[<ffffffff814f0084>] ? build_skb+0x34/0x1c0
>[<ffffffffa0639b11>] pktgen_thread_worker+0x5d1/0x1790 [pktgen]
>[<ffffffffa03ffb10>] ? igb_xmit_frame_ring+0xa30/0xa30 [igb]
>[<ffffffff8107ba20>] ? wake_up_bit+0x40/0x40
>[<ffffffff8107ba20>] ? wake_up_bit+0x40/0x40
>[<ffffffffa0639540>] ? spin+0x240/0x240 [pktgen]
>[<ffffffff8107b4e3>] kthread+0x93/0xa0
>[<ffffffff81615de4>] kernel_thread_helper+0x4/0x10
>[<ffffffff8107b450>] ? flush_kthread_worker+0x80/0x80
>[<ffffffff81615de0>] ? gs_change+0x13/0x13
>
>The root cause of why pktgen is not able to handle this case is due
>to comparison of signed (datalen) and unsigned data (sizeof), which
>eventually passes a huge number to skb_put().
>
>Signed-off-by: Nishank Trivedi <nistrive@cisco.com>
>---
> net/core/pktgen.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
>diff --git a/net/core/pktgen.c b/net/core/pktgen.c
>index cce9e53..148e73d 100644
>--- a/net/core/pktgen.c
>+++ b/net/core/pktgen.c
>@@ -2721,7 +2721,7 @@ static struct sk_buff *fill_packet_ipv4(struct
>net_device *odev,
> /* Eth + IPh + UDPh + mpls */
> datalen = pkt_dev->cur_pkt_size - 14 - 20 - 8 -
> pkt_dev->pkt_overhead;
>- if (datalen < sizeof(struct pktgen_hdr))
>+ if (datalen < 0 || datalen < sizeof(struct pktgen_hdr))
> datalen = sizeof(struct pktgen_hdr);
>
> udph->source = htons(pkt_dev->cur_udp_src);
>--
>1.7.11.4
>
^ permalink raw reply
* Re: [PATCH] Xen backend support for paged out grant targets.
From: Andres Lagar-Cavilla @ 2012-09-13 0:04 UTC (permalink / raw)
To: Konrad Rzeszutek Wilk
Cc: Andres Lagar-Cavilla, xen-devel, Ian Campbell, David Vrabel,
David Miller, linux-kernel, netdev
In-Reply-To: <7EF39A37-CC11-4AB8-8B36-F8CD3646F6D3@gridcentric.ca>
On Sep 12, 2012, at 4:21 PM, Andres Lagar-Cavilla wrote:
>
> On Sep 12, 2012, at 4:06 PM, Konrad Rzeszutek Wilk wrote:
>
>> On Wed, Sep 12, 2012 at 03:45:53PM -0400, Andres Lagar-Cavilla wrote:
>>> Since Xen-4.2, hvm domains may have portions of their memory paged out. When a
>>> foreign domain (such as dom0) attempts to map these frames, the map will
>>> initially fail. The hypervisor returns a suitable errno, and kicks an
>>> asynchronous page-in operation carried out by a helper. The foreign domain is
>>> expected to retry the mapping operation until it eventually succeeds. The
>>> foreign domain is not put to sleep because itself could be the one running the
>>> pager assist (typical scenario for dom0).
>>
>> Looks ok to me. You forgot to put on the CC LKML and netdev mailing list
>> so I did that for you.
> Thanks. I have a concern though (re-posting from xen-devel). I need to bring attention to the following hunk:
> diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
> index 682633b..5610fd8 100644
> --- a/drivers/net/xen-netback/netback.c
> +++ b/drivers/net/xen-netback/netback.c
> @@ -635,9 +635,7 @@ static void xen_netbk_rx_action(struct xen_netbk *netbk)
> return;
>
> BUG_ON(npo.copy_prod > ARRAY_SIZE(netbk->grant_copy_op));
> - ret = HYPERVISOR_grant_table_op(GNTTABOP_copy, &netbk->grant_copy_op,
> - npo.copy_prod);
> - BUG_ON(ret != 0);
> + gnttab_batch_copy_no_eagain(netbk->grant_copy_op, npo.copy_prod);
>
> It seems like the (extant) code passes a struct gnttab_copy ** to the grant table hypercall (&netbk->grant_copy_op, defined as struct gnttab_copy [])
>
> I "fixed" it to pass a struct gnttab_copy * (netbk->grant_copy_op, no '&'). This matches the other invocation of the grant copy hyper call (in netbk_tx_action). Did I fix it, though? I am confused as to how this could have ever worked.
Well, a bit of a faceslap moment for me.
netbk->grant_copy_op and &netbk->grant_copy_op yield the same pointer, thanks to obscure rule number foo:
"""Under ANSI/ISO Standard C, &array yields a pointer, of type pointer-to-array-of-T, to the entire array. Under pre-ANSI C, the & in &array generally elicited a warning, and was generally ignored. Under all C compilers, an unadorned reference to an array yields a pointer, of type pointer-to-T, to the array's first element. """
Please review patch as is.
Thanks and pardon the noise.
Andres
>
> Andres
>
>>
>>>
>>> This patch adds support for this mechanism for backend drivers using grant
>>> mapping and copying operations. Specifically, this covers the blkback and
>>> gntdev drivers (which map foregin grants), and the netback driver (which copies
>>> foreign grants).
>>>
>>> * Add GNTST_eagain, already exposed by Xen, to the grant interface.
>>> * Add a retry method for grants that fail with GNTST_eagain (i.e. because the
>>> target foregin frame is paged out).
>>> * Insert hooks with appropriate macro decorators in the aforementioned drivers.
>>>
>>> The retry loop is only invoked if the grant operation status is GNTST_eagain.
>>> It guarantees to leave a new status code different from GNTST_eagain. Any other
>>> status code results in identical code execution as before.
>>>
>>> The retry loop performs 256 attempts with increasing time intervals through a
>>> 32 second period. It uses msleep to yield while waiting for the next retry.
>>>
>>> V2 after feedback from David Vrabel:
>>> * Explicit MAX_DELAY instead of wrap-around delay into zero
>>> * Abstract GNTST_eagain check into core grant table code for netback module.
>>>
>>> Signed-off-by: Andres Lagar-Cavilla <andres@lagarcavilla.org>
>>> ---
>>> drivers/net/xen-netback/netback.c | 11 +++-------
>>> drivers/xen/grant-table.c | 26 ++++++++++++++++++++++++
>>> drivers/xen/xenbus/xenbus_client.c | 6 ++----
>>> include/xen/grant_table.h | 38 +++++++++++++++++++++++++++++++++++
>>> include/xen/interface/grant_table.h | 2 ++
>>> 5 files changed, 71 insertions(+), 12 deletions(-)
>>>
>>> diff --git a/drivers/net/xen-netback/netback.c b/drivers/net/xen-netback/netback.c
>>> index 682633b..fc40258 100644
>>> --- a/drivers/net/xen-netback/netback.c
>>> +++ b/drivers/net/xen-netback/netback.c
>>> @@ -635,9 +635,7 @@ static void xen_netbk_rx_action(struct xen_netbk *netbk)
>>> return;
>>>
>>> BUG_ON(npo.copy_prod > ARRAY_SIZE(netbk->grant_copy_op));
>>> - ret = HYPERVISOR_grant_table_op(GNTTABOP_copy, &netbk->grant_copy_op,
>>> - npo.copy_prod);
>>> - BUG_ON(ret != 0);
>>> + gnttab_batch_copy_retry_eagain(netbk->grant_copy_op, npo.copy_prod);
>>>
>>> while ((skb = __skb_dequeue(&rxq)) != NULL) {
>>> sco = (struct skb_cb_overlay *)skb->cb;
>>> @@ -1460,18 +1458,15 @@ static void xen_netbk_tx_submit(struct xen_netbk *netbk)
>>> static void xen_netbk_tx_action(struct xen_netbk *netbk)
>>> {
>>> unsigned nr_gops;
>>> - int ret;
>>>
>>> nr_gops = xen_netbk_tx_build_gops(netbk);
>>>
>>> if (nr_gops == 0)
>>> return;
>>> - ret = HYPERVISOR_grant_table_op(GNTTABOP_copy,
>>> - netbk->tx_copy_ops, nr_gops);
>>> - BUG_ON(ret);
>>>
>>> - xen_netbk_tx_submit(netbk);
>>> + gnttab_batch_copy_retry_eagain(netbk->tx_copy_ops, nr_gops);
>>>
>>> + xen_netbk_tx_submit(netbk);
>>> }
>>>
>>> static void xen_netbk_idx_release(struct xen_netbk *netbk, u16 pending_idx)
>>> diff --git a/drivers/xen/grant-table.c b/drivers/xen/grant-table.c
>>> index eea81cf..96543b2 100644
>>> --- a/drivers/xen/grant-table.c
>>> +++ b/drivers/xen/grant-table.c
>>> @@ -38,6 +38,7 @@
>>> #include <linux/vmalloc.h>
>>> #include <linux/uaccess.h>
>>> #include <linux/io.h>
>>> +#include <linux/delay.h>
>>> #include <linux/hardirq.h>
>>>
>>> #include <xen/xen.h>
>>> @@ -823,6 +824,26 @@ unsigned int gnttab_max_grant_frames(void)
>>> }
>>> EXPORT_SYMBOL_GPL(gnttab_max_grant_frames);
>>>
>>> +#define MAX_DELAY 256
>>> +void
>>> +gnttab_retry_eagain_gop(unsigned int cmd, void *gop, int16_t *status,
>>> + const char *func)
>>> +{
>>> + unsigned delay = 1;
>>> +
>>> + do {
>>> + BUG_ON(HYPERVISOR_grant_table_op(cmd, gop, 1));
>>> + if (*status == GNTST_eagain)
>>> + msleep(delay++);
>>> + } while ((*status == GNTST_eagain) && (delay < MAX_DELAY));
>>> +
>>> + if (delay >= MAX_DELAY) {
>>> + printk(KERN_ERR "%s: %s eagain grant\n", func, current->comm);
>>> + *status = GNTST_bad_page;
>>> + }
>>> +}
>>> +EXPORT_SYMBOL_GPL(gnttab_retry_eagain_gop);
>>> +
>>> int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops,
>>> struct gnttab_map_grant_ref *kmap_ops,
>>> struct page **pages, unsigned int count)
>>> @@ -836,6 +857,11 @@ int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops,
>>> if (ret)
>>> return ret;
>>>
>>> + /* Retry eagain maps */
>>> + for (i = 0; i < count; i++)
>>> + if (map_ops[i].status == GNTST_eagain)
>>> + gnttab_retry_eagain_map(map_ops + i);
>>> +
>>> if (xen_feature(XENFEAT_auto_translated_physmap))
>>> return ret;
>>>
>>> diff --git a/drivers/xen/xenbus/xenbus_client.c b/drivers/xen/xenbus/xenbus_client.c
>>> index b3e146e..a6e07ea 100644
>>> --- a/drivers/xen/xenbus/xenbus_client.c
>>> +++ b/drivers/xen/xenbus/xenbus_client.c
>>> @@ -490,8 +490,7 @@ static int xenbus_map_ring_valloc_pv(struct xenbus_device *dev,
>>>
>>> op.host_addr = arbitrary_virt_to_machine(pte).maddr;
>>>
>>> - if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
>>> - BUG();
>>> + gnttab_map_grant_retry_eagain(&op);
>>>
>>> if (op.status != GNTST_okay) {
>>> free_vm_area(area);
>>> @@ -572,8 +571,7 @@ int xenbus_map_ring(struct xenbus_device *dev, int gnt_ref,
>>> gnttab_set_map_op(&op, (unsigned long)vaddr, GNTMAP_host_map, gnt_ref,
>>> dev->otherend_id);
>>>
>>> - if (HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, &op, 1))
>>> - BUG();
>>> + gnttab_map_grant_retry_eagain(&op);
>>>
>>> if (op.status != GNTST_okay) {
>>> xenbus_dev_fatal(dev, op.status,
>>> diff --git a/include/xen/grant_table.h b/include/xen/grant_table.h
>>> index 11e27c3..c829c83 100644
>>> --- a/include/xen/grant_table.h
>>> +++ b/include/xen/grant_table.h
>>> @@ -43,6 +43,7 @@
>>> #include <xen/interface/grant_table.h>
>>>
>>> #include <asm/xen/hypervisor.h>
>>> +#include <asm/xen/hypercall.h>
>>>
>>> #include <xen/features.h>
>>>
>>> @@ -183,6 +184,43 @@ unsigned int gnttab_max_grant_frames(void);
>>>
>>> #define gnttab_map_vaddr(map) ((void *)(map.host_virt_addr))
>>>
>>> +/* Retry a grant map/copy operation when the hypervisor returns GNTST_eagain.
>>> + * This is typically due to paged out target frames.
>>> + * Generic entry-point, use macro decorators below for specific grant
>>> + * operations.
>>> + * Will retry for 1, 2, ... 255 ms, i.e. 256 times during 32 seconds.
>>> + * Return value in *status guaranteed to no longer be GNTST_eagain. */
>>> +void gnttab_retry_eagain_gop(unsigned int cmd, void *gop, int16_t *status,
>>> + const char *func);
>>> +
>>> +#define gnttab_retry_eagain_map(_gop) \
>>> + gnttab_retry_eagain_gop(GNTTABOP_map_grant_ref, (_gop), \
>>> + &(_gop)->status, __func__)
>>> +
>>> +#define gnttab_retry_eagain_copy(_gop) \
>>> + gnttab_retry_eagain_gop(GNTTABOP_copy, (_gop), \
>>> + &(_gop)->status, __func__)
>>> +
>>> +static inline void
>>> +gnttab_map_grant_retry_eagain(struct gnttab_map_grant_ref *op)
>>> +{
>>> + BUG_ON((HYPERVISOR_grant_table_op(GNTTABOP_map_grant_ref, op, 1)));
>>> + if (op->status == GNTST_eagain)
>>> + gnttab_retry_eagain_map(op);
>>> +}
>>> +
>>> +static inline void
>>> +gnttab_batch_copy_retry_eagain(struct gnttab_copy *batch, unsigned count)
>>> +{
>>> + unsigned i;
>>> + struct gnttab_copy *op;
>>> +
>>> + BUG_ON(HYPERVISOR_grant_table_op(GNTTABOP_copy, batch, count));
>>> + for (i = 0, op = batch; i < count; i++, op++)
>>> + if (op->status == GNTST_eagain)
>>> + gnttab_retry_eagain_copy(op);
>>> +}
>>> +
>>> int gnttab_map_refs(struct gnttab_map_grant_ref *map_ops,
>>> struct gnttab_map_grant_ref *kmap_ops,
>>> struct page **pages, unsigned int count);
>>> diff --git a/include/xen/interface/grant_table.h b/include/xen/interface/grant_table.h
>>> index 7da811b..66cb734 100644
>>> --- a/include/xen/interface/grant_table.h
>>> +++ b/include/xen/interface/grant_table.h
>>> @@ -520,6 +520,7 @@ DEFINE_GUEST_HANDLE_STRUCT(gnttab_get_version);
>>> #define GNTST_permission_denied (-8) /* Not enough privilege for operation. */
>>> #define GNTST_bad_page (-9) /* Specified page was invalid for op. */
>>> #define GNTST_bad_copy_arg (-10) /* copy arguments cross page boundary */
>>> +#define GNTST_eagain (-12) /* Retry. */
>>>
>>> #define GNTTABOP_error_msgs { \
>>> "okay", \
>>> @@ -533,6 +534,7 @@ DEFINE_GUEST_HANDLE_STRUCT(gnttab_get_version);
>>> "permission denied", \
>>> "bad page", \
>>> "copy arguments cross page boundary" \
>>> + "retry" \
>>> }
>>>
>>> #endif /* __XEN_PUBLIC_GRANT_TABLE_H__ */
>>> --
>>> 1.7.9.5
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at http://vger.kernel.org/majordomo-info.html
>> Please read the FAQ at http://www.tux.org/lkml/
>
^ permalink raw reply
* Re: [PATCH 0/5] dev_<level> and dynamic_debug cleanups
From: Joe Perches @ 2012-09-13 1:13 UTC (permalink / raw)
To: Jason Baron
Cc: Greg Kroah-Hartman, Jim Cromie, Kay Sievers, Andrew Morton,
netdev, David S. Miller, linux-kernel
In-Reply-To: <20120906175313.GC9786@redhat.com>
On Thu, 2012-09-06 at 13:53 -0400, Jason Baron wrote:
> On Thu, Sep 06, 2012 at 09:13:59AM -0700, Greg Kroah-Hartman wrote:
> > Jason, any ACK on these, or any of the other random dynamic debug
> > patches floating around? What am I supposed to be applying here?
[]
> I just posted some follow up comments to Joe, so let's see where that
> discussion goes.
Jason, I think you need to ack these original 5 patches.
^ permalink raw reply
* Re: [REVIEW][PATCH 12/15] userns: Convert drm to use kuid and kgid and struct pid where appropriate
From: Dave Airlie @ 2012-09-13 1:31 UTC (permalink / raw)
To: Eric W. Biederman
Cc: linux-kernel, netdev, linux-fsdevel, Serge E. Hallyn,
David Miller, David Airlie, dri-devel
In-Reply-To: <87mx1iecwi.fsf@xmission.com>
> Blink Blink this had not been converted to use struct pid ages ago?
>
> - On drm open capture the openers kuid and struct pid.
> - On drm close release the kuid and struct pid
> - When reporting the uid and pid convert the kuid and struct pid
> into values in the appropriate namespace.
>
Hi Eric,
I'm fine with this seems okay, do you want me to merge it via drm-next?
Dave.
> Cc: David Airlie <airlied@linux.ie>
> Cc: dri-devel@lists.freedesktop.org
> Acked-by: Serge Hallyn <serge.hallyn@canonical.com>
> Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
> ---
> drivers/gpu/drm/drm_fops.c | 3 ++-
> drivers/gpu/drm/drm_info.c | 5 +++--
> drivers/gpu/drm/drm_ioctl.c | 4 ++--
> include/drm/drmP.h | 4 ++--
> init/Kconfig | 1 -
> 5 files changed, 9 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/gpu/drm/drm_fops.c b/drivers/gpu/drm/drm_fops.c
> index 5062eec..433d2fa 100644
> --- a/drivers/gpu/drm/drm_fops.c
> +++ b/drivers/gpu/drm/drm_fops.c
> @@ -251,7 +251,7 @@ static int drm_open_helper(struct inode *inode, struct file *filp,
> filp->private_data = priv;
> priv->filp = filp;
> priv->uid = current_euid();
> - priv->pid = task_pid_nr(current);
> + priv->pid = get_pid(task_pid(current));
> priv->minor = idr_find(&drm_minors_idr, minor_id);
> priv->ioctl_count = 0;
> /* for compatibility root is always authenticated */
> @@ -524,6 +524,7 @@ int drm_release(struct inode *inode, struct file *filp)
> if (drm_core_check_feature(dev, DRIVER_PRIME))
> drm_prime_destroy_file_private(&file_priv->prime);
>
> + put_pid(file_priv->pid);
> kfree(file_priv);
>
> /* ========================================================
> diff --git a/drivers/gpu/drm/drm_info.c b/drivers/gpu/drm/drm_info.c
> index 8928edb..eb0af39 100644
> --- a/drivers/gpu/drm/drm_info.c
> +++ b/drivers/gpu/drm/drm_info.c
> @@ -191,8 +191,9 @@ int drm_clients_info(struct seq_file *m, void *data)
> seq_printf(m, "%c %3d %5d %5d %10u %10lu\n",
> priv->authenticated ? 'y' : 'n',
> priv->minor->index,
> - priv->pid,
> - priv->uid, priv->magic, priv->ioctl_count);
> + pid_vnr(priv->pid),
> + from_kuid_munged(seq_user_ns(m), priv->uid),
> + priv->magic, priv->ioctl_count);
> }
> mutex_unlock(&dev->struct_mutex);
> return 0;
> diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c
> index 64a62c6..39a4383 100644
> --- a/drivers/gpu/drm/drm_ioctl.c
> +++ b/drivers/gpu/drm/drm_ioctl.c
> @@ -215,8 +215,8 @@ int drm_getclient(struct drm_device *dev, void *data,
> list_for_each_entry(pt, &dev->filelist, lhead) {
> if (i++ >= idx) {
> client->auth = pt->authenticated;
> - client->pid = pt->pid;
> - client->uid = pt->uid;
> + client->pid = pid_vnr(pt->pid);
> + client->uid = from_kuid_munged(current_user_ns(), pt->uid);
> client->magic = pt->magic;
> client->iocs = pt->ioctl_count;
> mutex_unlock(&dev->struct_mutex);
> diff --git a/include/drm/drmP.h b/include/drm/drmP.h
> index d6b67bb..9bc5c6a 100644
> --- a/include/drm/drmP.h
> +++ b/include/drm/drmP.h
> @@ -426,8 +426,8 @@ struct drm_prime_file_private {
> /** File private data */
> struct drm_file {
> int authenticated;
> - pid_t pid;
> - uid_t uid;
> + struct pid *pid;
> + kuid_t uid;
> drm_magic_t magic;
> unsigned long ioctl_count;
> struct list_head lhead;
> diff --git a/init/Kconfig b/init/Kconfig
> index d849ba2..2a388e5 100644
> --- a/init/Kconfig
> +++ b/init/Kconfig
> @@ -930,7 +930,6 @@ config UIDGID_CONVERTED
> depends on FS_POSIX_ACL = n
> depends on QUOTA = n
> depends on QUOTACTL = n
> - depends on DRM = n
>
> # Networking
> depends on NET_9P = n
> --
> 1.7.5.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply
* Re: [REVIEW][PATCH 12/15] userns: Convert drm to use kuid and kgid and struct pid where appropriate
From: Eric W. Biederman @ 2012-09-13 2:14 UTC (permalink / raw)
To: Dave Airlie
Cc: linux-kernel, netdev, linux-fsdevel, Serge E. Hallyn,
David Miller, David Airlie, dri-devel
In-Reply-To: <CAPM=9ty=0=+w8VaFC9QhajUkYwmym_JaWR9sbwmgw5tCKg5nGw@mail.gmail.com>
Dave Airlie <airlied@gmail.com> writes:
>> Blink Blink this had not been converted to use struct pid ages ago?
>>
>> - On drm open capture the openers kuid and struct pid.
>> - On drm close release the kuid and struct pid
>> - When reporting the uid and pid convert the kuid and struct pid
>> into values in the appropriate namespace.
>>
>
> Hi Eric,
>
> I'm fine with this seems okay, do you want me to merge it via
> drm-next?
My plan is to merge it via my user namespace tree. And since you have
responed positively I will add your acked-by. There are some nice
synergies when I get all of the changes in one tree.
If for some reason you want to carry this in your drm tree we can work
something out.
In this case I expect the change isn't big enough to worry about.
Eric
^ permalink raw reply
* Re: [PATCH 0/5] dev_<level> and dynamic_debug cleanups
From: Jason Baron @ 2012-09-13 2:39 UTC (permalink / raw)
To: Joe Perches
Cc: Greg Kroah-Hartman, Jim Cromie, Kay Sievers, Andrew Morton,
netdev, David S. Miller, linux-kernel
In-Reply-To: <1347498810.2749.0.camel@joe2Laptop>
On Wed, Sep 12, 2012 at 06:13:30PM -0700, Joe Perches wrote:
> On Thu, 2012-09-06 at 13:53 -0400, Jason Baron wrote:
> > On Thu, Sep 06, 2012 at 09:13:59AM -0700, Greg Kroah-Hartman wrote:
> > > Jason, any ACK on these, or any of the other random dynamic debug
> > > patches floating around? What am I supposed to be applying here?
> []
> > I just posted some follow up comments to Joe, so let's see where that
> > discussion goes.
>
> Jason, I think you need to ack these original 5 patches.
>
Hi,
Yes, they are certainly an improvement. Please add to the series:
Acked-by: Jason Baron <jbaron@redhat.com>
Thanks!
-Jason
^ permalink raw reply
* Re: [PATCH 0/5] dev_<level> and dynamic_debug cleanups
From: Greg Kroah-Hartman @ 2012-09-13 2:55 UTC (permalink / raw)
To: Jason Baron
Cc: Joe Perches, Jim Cromie, Kay Sievers, Andrew Morton, netdev,
David S. Miller, linux-kernel
In-Reply-To: <20120913023948.GC3214@redhat.com>
On Wed, Sep 12, 2012 at 10:39:48PM -0400, Jason Baron wrote:
> On Wed, Sep 12, 2012 at 06:13:30PM -0700, Joe Perches wrote:
> > On Thu, 2012-09-06 at 13:53 -0400, Jason Baron wrote:
> > > On Thu, Sep 06, 2012 at 09:13:59AM -0700, Greg Kroah-Hartman wrote:
> > > > Jason, any ACK on these, or any of the other random dynamic debug
> > > > patches floating around? What am I supposed to be applying here?
> > []
> > > I just posted some follow up comments to Joe, so let's see where that
> > > discussion goes.
> >
> > Jason, I think you need to ack these original 5 patches.
> >
>
> Hi,
>
> Yes, they are certainly an improvement. Please add to the series:
>
> Acked-by: Jason Baron <jbaron@redhat.com>
Um, can someone please resend these with the ack so I can pick them up?
They are long gone from my mboxes...
greg k-h
^ permalink raw reply
* Re: [PATCH net-next 1/2] ipv6: force RTF_NONEXTHOP for SIT device
From: Eric Dumazet @ 2012-09-13 2:59 UTC (permalink / raw)
To: David Miller
Cc: netdev, Lorenzo Colitti, Maciej Żenczykowski, Tom Herbert
In-Reply-To: <1347451266.13103.882.camel@edumazet-glaptop>
On Wed, 2012-09-12 at 14:01 +0200, Eric Dumazet wrote:
> From: Eric Dumazet <edumazet@google.com>
>
> We have special handling of SIT devices in addrconf_prefix_route()
> to avoid using a neighbour for each destination.
>
> If routing entry is :
>
> ip -6 route add 2001:db8::/64 dev sit1
>
> Then the kernel will create a new route for every new address
> under 2001:db8::/64 that we send a packet to (potentially, 2^64
> routes).
>
> Under load, we immediately get the infamous "Neighbour table overflow"
> message and machine eventually crash.
>
> This does not happen if we specify a next-hop explicitly, like so:
>
> ip -6 route add 2001:db8::/64 via fe80:: dev sit1
>
> We can avoid this hassle doing the SIT test in ip6_route_add() instead
> of addrconf_prefix_route().
>
> This permits ip6_pol_route() to clone route instead of calling
> rt6_alloc_cow() and allocate a neighbour
>
> Reported-by: Lorenzo Colitti <lorenzo@google.com>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Cc: Maciej Żenczykowski <maze@google.com>
> Cc: Tom Herbert <therbert@google.com>
> ---
> net/ipv6/addrconf.c | 10 ----------
> net/ipv6/route.c | 9 +++++++++
> 2 files changed, 9 insertions(+), 10 deletions(-)
>
> diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
> index 1237d5d..c6837d2 100644
> --- a/net/ipv6/addrconf.c
> +++ b/net/ipv6/addrconf.c
> @@ -1679,16 +1679,6 @@ addrconf_prefix_route(struct in6_addr *pfx, int plen, struct net_device *dev,
> };
>
> cfg.fc_dst = *pfx;
> -
> - /* Prevent useless cloning on PtP SIT.
> - This thing is done here expecting that the whole
> - class of non-broadcast devices need not cloning.
> - */
> -#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE)
> - if (dev->type == ARPHRD_SIT && (dev->flags & IFF_POINTOPOINT))
> - cfg.fc_flags |= RTF_NONEXTHOP;
> -#endif
> -
> ip6_route_add(&cfg);
> }
>
> diff --git a/net/ipv6/route.c b/net/ipv6/route.c
> index 399613b..d4ba3fc 100644
> --- a/net/ipv6/route.c
> +++ b/net/ipv6/route.c
> @@ -1540,6 +1540,15 @@ int ip6_route_add(struct fib6_config *cfg)
> } else
> rt->rt6i_prefsrc.plen = 0;
>
> + /* Prevent useless cloning on PtP SIT.
> + * This thing is done here expecting that the whole
> + * class of non-broadcast devices need not cloning.
> + */
> +#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE)
> + if (dev && dev->type == ARPHRD_SIT && (dev->flags & IFF_POINTOPOINT))
> + cfg->fc_flags |= RTF_NONEXTHOP;
> +#endif
> +
> if (cfg->fc_flags & (RTF_GATEWAY | RTF_NONEXTHOP)) {
> err = rt6_bind_neighbour(rt, dev);
> if (err)
>
Please hold this patch, I'll send a v2, based on excellent feedback from
Lorenzo.
Idea is to just do :
if (dev->flags & (IFF_POINTOPOINT | IFF_LOOPBACK))
cfg->fc_flags |= RFT_NONEXTHOP;
(no mention of SIT anymore, and a change in the title patch)
^ permalink raw reply
* [PATCH 1/5] dev_dbg/dynamic_debug: Update to use printk_emit, optimize stack
From: Joe Perches @ 2012-09-13 3:11 UTC (permalink / raw)
To: Andrew Morton, Greg Kroah-Hartman, Jason Baron
Cc: David S. Miller, Jim Cromie, Kay Sievers, netdev, linux-kernel
In-Reply-To: <cover.1345978012.git.joe@perches.com>
commit c4e00daaa9
("driver-core: extend dev_printk() to pass structured data")
changed __dev_printk and broke dynamic-debug's ability to control the
dynamic prefix of dev_dbg(dev,..).
commit af7f2158fd
("drivers-core: make structured logging play nice with dynamic-debug")
made a minimal correction.
The current dynamic debug code uses up to 3 recursion levels via %pV.
This can consume quite a bit of stack. Directly call printk_emit to
reduce the recursion depth.
These changes include:
dev_dbg:
o Create and use function create_syslog_header to format the syslog
header for printk_emit uses.
o Call create_syslog_header and neaten __dev_printk
o Make __dev_printk static not global
o Remove include header declaration of __dev_printk
o Remove now unused EXPORT_SYMBOL() of __dev_printk
o Whitespace neatening
dynamic_dev_dbg:
o Remove KERN_DEBUG from dynamic_emit_prefix
o Call create_syslog_header and printk_emit
o Whitespace neatening
Signed-off-by: Joe Perches <joe@perches.com>
Acked-by: David S. Miller <davem@davemloft.net>
Tested-by: Jim Cromie <jim.cromie@gmail.com>
Acked-by: Jason Baron <jbaron@redhat.com>
---
drivers/base/core.c | 64 +++++++++++++++++++++++++----------------------
include/linux/device.h | 8 +++---
lib/dynamic_debug.c | 39 +++++++++++++++++++++-------
3 files changed, 67 insertions(+), 44 deletions(-)
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 5e6e00b..d46b635 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -1861,26 +1861,19 @@ void device_shutdown(void)
*/
#ifdef CONFIG_PRINTK
-int __dev_printk(const char *level, const struct device *dev,
- struct va_format *vaf)
+int create_syslog_header(const struct device *dev, char *hdr, size_t hdrlen)
{
- char dict[128];
- const char *level_extra = "";
- size_t dictlen = 0;
const char *subsys;
-
- if (!dev)
- return printk("%s(NULL device *): %pV", level, vaf);
+ size_t pos = 0;
if (dev->class)
subsys = dev->class->name;
else if (dev->bus)
subsys = dev->bus->name;
else
- goto skip;
+ return 0;
- dictlen += snprintf(dict + dictlen, sizeof(dict) - dictlen,
- "SUBSYSTEM=%s", subsys);
+ pos += snprintf(hdr + pos, hdrlen - pos, "SUBSYSTEM=%s", subsys);
/*
* Add device identifier DEVICE=:
@@ -1896,32 +1889,41 @@ int __dev_printk(const char *level, const struct device *dev,
c = 'b';
else
c = 'c';
- dictlen++;
- dictlen += snprintf(dict + dictlen, sizeof(dict) - dictlen,
- "DEVICE=%c%u:%u",
- c, MAJOR(dev->devt), MINOR(dev->devt));
+ pos++;
+ pos += snprintf(hdr + pos, hdrlen - pos,
+ "DEVICE=%c%u:%u",
+ c, MAJOR(dev->devt), MINOR(dev->devt));
} else if (strcmp(subsys, "net") == 0) {
struct net_device *net = to_net_dev(dev);
- dictlen++;
- dictlen += snprintf(dict + dictlen, sizeof(dict) - dictlen,
- "DEVICE=n%u", net->ifindex);
+ pos++;
+ pos += snprintf(hdr + pos, hdrlen - pos,
+ "DEVICE=n%u", net->ifindex);
} else {
- dictlen++;
- dictlen += snprintf(dict + dictlen, sizeof(dict) - dictlen,
- "DEVICE=+%s:%s", subsys, dev_name(dev));
+ pos++;
+ pos += snprintf(hdr + pos, hdrlen - pos,
+ "DEVICE=+%s:%s", subsys, dev_name(dev));
}
-skip:
- if (level[2])
- level_extra = &level[2]; /* skip past KERN_SOH "L" */
- return printk_emit(0, level[1] - '0',
- dictlen ? dict : NULL, dictlen,
- "%s %s: %s%pV",
- dev_driver_string(dev), dev_name(dev),
- level_extra, vaf);
+ return pos;
+}
+EXPORT_SYMBOL(create_syslog_header);
+
+static int __dev_printk(const char *level, const struct device *dev,
+ struct va_format *vaf)
+{
+ char hdr[128];
+ size_t hdrlen;
+
+ if (!dev)
+ return printk("%s(NULL device *): %pV", level, vaf);
+
+ hdrlen = create_syslog_header(dev, hdr, sizeof(hdr));
+
+ return printk_emit(0, level[1] - '0', hdrlen ? hdr : NULL, hdrlen,
+ "%s %s: %pV",
+ dev_driver_string(dev), dev_name(dev), vaf);
}
-EXPORT_SYMBOL(__dev_printk);
int dev_printk(const char *level, const struct device *dev,
const char *fmt, ...)
@@ -1936,6 +1938,7 @@ int dev_printk(const char *level, const struct device *dev,
vaf.va = &args;
r = __dev_printk(level, dev, &vaf);
+
va_end(args);
return r;
@@ -1955,6 +1958,7 @@ int func(const struct device *dev, const char *fmt, ...) \
vaf.va = &args; \
\
r = __dev_printk(kern_level, dev, &vaf); \
+ \
va_end(args); \
\
return r; \
diff --git a/include/linux/device.h b/include/linux/device.h
index 52a5f15..4800d73 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -891,12 +891,12 @@ extern const char *dev_driver_string(const struct device *dev);
#ifdef CONFIG_PRINTK
-extern int __dev_printk(const char *level, const struct device *dev,
- struct va_format *vaf);
+extern int create_syslog_header(const struct device *dev,
+ char *hdr, size_t hdrlen);
+
extern __printf(3, 4)
int dev_printk(const char *level, const struct device *dev,
- const char *fmt, ...)
- ;
+ const char *fmt, ...);
extern __printf(2, 3)
int dev_emerg(const struct device *dev, const char *fmt, ...);
extern __printf(2, 3)
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 7ca29a0..29ff2e4 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -521,25 +521,25 @@ static char *dynamic_emit_prefix(const struct _ddebug *desc, char *buf)
int pos_after_tid;
int pos = 0;
- pos += snprintf(buf + pos, remaining(pos), "%s", KERN_DEBUG);
+ *buf = '\0';
+
if (desc->flags & _DPRINTK_FLAGS_INCL_TID) {
if (in_interrupt())
- pos += snprintf(buf + pos, remaining(pos), "%s ",
- "<intr>");
+ pos += snprintf(buf + pos, remaining(pos), "<intr> ");
else
pos += snprintf(buf + pos, remaining(pos), "[%d] ",
- task_pid_vnr(current));
+ task_pid_vnr(current));
}
pos_after_tid = pos;
if (desc->flags & _DPRINTK_FLAGS_INCL_MODNAME)
pos += snprintf(buf + pos, remaining(pos), "%s:",
- desc->modname);
+ desc->modname);
if (desc->flags & _DPRINTK_FLAGS_INCL_FUNCNAME)
pos += snprintf(buf + pos, remaining(pos), "%s:",
- desc->function);
+ desc->function);
if (desc->flags & _DPRINTK_FLAGS_INCL_LINENO)
pos += snprintf(buf + pos, remaining(pos), "%d:",
- desc->lineno);
+ desc->lineno);
if (pos - pos_after_tid)
pos += snprintf(buf + pos, remaining(pos), " ");
if (pos >= PREFIX_SIZE)
@@ -559,9 +559,13 @@ int __dynamic_pr_debug(struct _ddebug *descriptor, const char *fmt, ...)
BUG_ON(!fmt);
va_start(args, fmt);
+
vaf.fmt = fmt;
vaf.va = &args;
- res = printk("%s%pV", dynamic_emit_prefix(descriptor, buf), &vaf);
+
+ res = printk(KERN_DEBUG "%s%pV",
+ dynamic_emit_prefix(descriptor, buf), &vaf);
+
va_end(args);
return res;
@@ -574,15 +578,30 @@ int __dynamic_dev_dbg(struct _ddebug *descriptor,
struct va_format vaf;
va_list args;
int res;
- char buf[PREFIX_SIZE];
BUG_ON(!descriptor);
BUG_ON(!fmt);
va_start(args, fmt);
+
vaf.fmt = fmt;
vaf.va = &args;
- res = __dev_printk(dynamic_emit_prefix(descriptor, buf), dev, &vaf);
+
+ if (!dev) {
+ res = printk(KERN_DEBUG "(NULL device *): %pV", &vaf);
+ } else {
+ char buf[PREFIX_SIZE];
+ char dict[128];
+ size_t dictlen;
+
+ dictlen = create_syslog_header(dev, dict, sizeof(dict));
+
+ res = printk_emit(0, 7, dictlen ? dict : NULL, dictlen,
+ "%s%s %s: %pV",
+ dynamic_emit_prefix(descriptor, buf),
+ dev_driver_string(dev), dev_name(dev), &vaf);
+ }
+
va_end(args);
return res;
--
1.7.8.111.gad25c.dirty
^ permalink raw reply related
* [PATCH 2/5] netdev_printk/dynamic_netdev_dbg: Directly call printk_emit
From: Joe Perches @ 2012-09-13 3:12 UTC (permalink / raw)
To: Andrew Morton, David S. Miller, Jason Baron
Cc: Greg Kroah-Hartman, Jim Cromie, Kay Sievers, netdev, linux-kernel
In-Reply-To: <cover.1345978012.git.joe@perches.com>
A lot of stack is used in recursive printks with %pV.
Using multiple levels of %pV (a logging function with %pV
that calls another logging function with %pV) can consume
more stack than necessary.
Avoid excessive stack use by not calling dev_printk from
netdev_printk and dynamic_netdev_dbg. Duplicate the logic
and form of dev_printk instead.
Make __netdev_printk static.
Remove EXPORT_SYMBOL(__netdev_printk)
Whitespace and brace style neatening.
Signed-off-by: Joe Perches <joe@perches.com>
Acked-by: David S. Miller <davem@davemloft.net>
Tested-by: Jim Cromie <jim.cromie@gmail.com>
Acked-by: Jason Baron <jbaron@redhat.com>
---
include/linux/netdevice.h | 3 ---
lib/dynamic_debug.c | 26 +++++++++++++++++++++++---
net/core/dev.c | 24 +++++++++++++++++-------
3 files changed, 40 insertions(+), 13 deletions(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 59dc05f3..5f49cc0 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -2720,9 +2720,6 @@ static inline const char *netdev_name(const struct net_device *dev)
return dev->name;
}
-extern int __netdev_printk(const char *level, const struct net_device *dev,
- struct va_format *vaf);
-
extern __printf(3, 4)
int netdev_printk(const char *level, const struct net_device *dev,
const char *format, ...);
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 29ff2e4..2a29f4e 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -611,20 +611,40 @@ EXPORT_SYMBOL(__dynamic_dev_dbg);
#ifdef CONFIG_NET
int __dynamic_netdev_dbg(struct _ddebug *descriptor,
- const struct net_device *dev, const char *fmt, ...)
+ const struct net_device *dev, const char *fmt, ...)
{
struct va_format vaf;
va_list args;
int res;
- char buf[PREFIX_SIZE];
BUG_ON(!descriptor);
BUG_ON(!fmt);
va_start(args, fmt);
+
vaf.fmt = fmt;
vaf.va = &args;
- res = __netdev_printk(dynamic_emit_prefix(descriptor, buf), dev, &vaf);
+
+ if (dev && dev->dev.parent) {
+ char buf[PREFIX_SIZE];
+ char dict[128];
+ size_t dictlen;
+
+ dictlen = create_syslog_header(dev->dev.parent,
+ dict, sizeof(dict));
+
+ res = printk_emit(0, 7, dictlen ? dict : NULL, dictlen,
+ "%s%s %s: %s: %pV",
+ dynamic_emit_prefix(descriptor, buf),
+ dev_driver_string(dev->dev.parent),
+ dev_name(dev->dev.parent),
+ netdev_name(dev), &vaf);
+ } else if (dev) {
+ res = printk(KERN_DEBUG "%s: %pV", netdev_name(dev), &vaf);
+ } else {
+ res = printk(KERN_DEBUG "(NULL net_device): %pV", &vaf);
+ }
+
va_end(args);
return res;
diff --git a/net/core/dev.c b/net/core/dev.c
index 8398836..a588145 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -6422,22 +6422,30 @@ const char *netdev_drivername(const struct net_device *dev)
return empty;
}
-int __netdev_printk(const char *level, const struct net_device *dev,
+static int __netdev_printk(const char *level, const struct net_device *dev,
struct va_format *vaf)
{
int r;
- if (dev && dev->dev.parent)
- r = dev_printk(level, dev->dev.parent, "%s: %pV",
- netdev_name(dev), vaf);
- else if (dev)
+ if (dev && dev->dev.parent) {
+ char dict[128];
+ size_t dictlen = create_syslog_header(dev->dev.parent,
+ dict, sizeof(dict));
+
+ r = printk_emit(0, level[1] - '0',
+ dictlen ? dict : NULL, dictlen,
+ "%s %s: %s: %pV",
+ dev_driver_string(dev->dev.parent),
+ dev_name(dev->dev.parent),
+ netdev_name(dev), vaf);
+ } else if (dev) {
r = printk("%s%s: %pV", level, netdev_name(dev), vaf);
- else
+ } else {
r = printk("%s(NULL net_device): %pV", level, vaf);
+ }
return r;
}
-EXPORT_SYMBOL(__netdev_printk);
int netdev_printk(const char *level, const struct net_device *dev,
const char *format, ...)
@@ -6452,6 +6460,7 @@ int netdev_printk(const char *level, const struct net_device *dev,
vaf.va = &args;
r = __netdev_printk(level, dev, &vaf);
+
va_end(args);
return r;
@@ -6471,6 +6480,7 @@ int func(const struct net_device *dev, const char *fmt, ...) \
vaf.va = &args; \
\
r = __netdev_printk(level, dev, &vaf); \
+ \
va_end(args); \
\
return r; \
--
1.7.8.111.gad25c.dirty
^ permalink raw reply related
* Re: [RFC/RFT 14/15] rtlwifi: Modify files for addition of rtl8723ae
From: Julian Calaby @ 2012-09-13 3:11 UTC (permalink / raw)
To: Larry Finger; +Cc: linville, linux-wireless, netdev, chaoming_li
In-Reply-To: <1347483294-6943-15-git-send-email-Larry.Finger@lwfinger.net>
Hi Larry,
On Thu, Sep 13, 2012 at 6:54 AM, Larry Finger <Larry.Finger@lwfinger.net> wrote:
> This patch modifies the files of rtlwifi for the addition of a new driver
> to handle the Realtek RTL8723AE wireless device, and introduces a new
> routine to maintaim statistics that will be used later for roaming.
>
> Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
> Cc: <chaoming_li@realsil.com.cn>
> ---
> drivers/net/wireless/rtlwifi/debug.h | 2 +
> drivers/net/wireless/rtlwifi/pci.h | 1 +
> drivers/net/wireless/rtlwifi/stats.c | 274 ++++++++++++++++++++++++++++++++++
> drivers/net/wireless/rtlwifi/stats.h | 47 ++++++
> 4 files changed, 324 insertions(+)
> create mode 100644 drivers/net/wireless/rtlwifi/stats.c
> create mode 100644 drivers/net/wireless/rtlwifi/stats.h
>
> diff --git a/drivers/net/wireless/rtlwifi/debug.h b/drivers/net/wireless/rtlwifi/debug.h
> index 07493d2..b81e299 100644
> --- a/drivers/net/wireless/rtlwifi/debug.h
> +++ b/drivers/net/wireless/rtlwifi/debug.h
> @@ -106,6 +106,8 @@
> #define COMP_REGD BIT(27)
> #define COMP_CHAN BIT(28)
> #define COMP_USB BIT(29)
> +#define COMP_EASY_CONCURRENT BIT(29)
Is this supposed to be bit #29 - I notice that COMP_USB is also bit 29.
Thanks,
--
Julian Calaby
Email: julian.calaby@gmail.com
Profile: http://www.google.com/profiles/julian.calaby/
.Plan: http://sites.google.com/site/juliancalaby/
^ permalink raw reply
* [PATCH 3/5] netdev_printk/netif_printk: Remove a superfluous logging colon
From: Joe Perches @ 2012-09-13 3:13 UTC (permalink / raw)
To: Andrew Morton, Jason Baron
Cc: Greg Kroah-Hartman, David S. Miller, Jim Cromie, Kay Sievers,
netdev, linux-kernel
In-Reply-To: <cover.1345978012.git.joe@perches.com>
netdev_printk originally called dev_printk with %pV.
This style emitted the complete dev_printk header with
a colon followed by the netdev_name prefix followed
by a colon.
Now that netdev_printk does not call dev_printk, the
extra colon is superfluous. Remove it.
Example:
old: sky2 0000:02:00.0: eth0: Link is up at 100 Mbps, full duplex, flow control both
new: sky2 0000:02:00.0 eth0: Link is up at 100 Mbps, full duplex, flow control both
Signed-off-by: Joe Perches <joe@perches.com>
Acked-by: David S. Miller <davem@davemloft.net>
Tested-by: Jim Cromie <jim.cromie@gmail.com>
Acked-by: Jason Baron <jbaron@redhat.com>
---
lib/dynamic_debug.c | 2 +-
net/core/dev.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 2a29f4e..6b3ebab 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -634,7 +634,7 @@ int __dynamic_netdev_dbg(struct _ddebug *descriptor,
dict, sizeof(dict));
res = printk_emit(0, 7, dictlen ? dict : NULL, dictlen,
- "%s%s %s: %s: %pV",
+ "%s%s %s %s: %pV",
dynamic_emit_prefix(descriptor, buf),
dev_driver_string(dev->dev.parent),
dev_name(dev->dev.parent),
diff --git a/net/core/dev.c b/net/core/dev.c
index a588145..1ec186a 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -6434,7 +6434,7 @@ static int __netdev_printk(const char *level, const struct net_device *dev,
r = printk_emit(0, level[1] - '0',
dictlen ? dict : NULL, dictlen,
- "%s %s: %s: %pV",
+ "%s %s %s: %pV",
dev_driver_string(dev->dev.parent),
dev_name(dev->dev.parent),
netdev_name(dev), vaf);
--
1.7.8.111.gad25c.dirty
^ permalink raw reply related
* [PATCH 4/5] dev: Add dev_vprintk_emit and dev_printk_emit
From: Joe Perches @ 2012-09-13 3:13 UTC (permalink / raw)
To: Andrew Morton, Greg Kroah-Hartman
Cc: David S. Miller, Jason Baron, Jim Cromie, Kay Sievers, netdev,
linux-kernel
In-Reply-To: <cover.1345978012.git.joe@perches.com>
Add utility functions to consolidate the use of
create_syslog_header and vprintk_emit.
This allows conversion of logging functions that
call create_syslog_header and then call vprintk_emit
or printk_emit to the dev_ equivalents.
Signed-off-by: Joe Perches <joe@perches.com>
Acked-by: David S. Miller <davem@davemloft.net>
Tested-by: Jim Cromie <jim.cromie@gmail.com>
Acked-by: Jason Baron <jbaron@redhat.com>
---
drivers/base/core.c | 27 +++++++++++++++++++++++++++
include/linux/device.h | 11 +++++++++++
2 files changed, 38 insertions(+), 0 deletions(-)
diff --git a/drivers/base/core.c b/drivers/base/core.c
index d46b635..ffccb64 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -1909,6 +1909,33 @@ int create_syslog_header(const struct device *dev, char *hdr, size_t hdrlen)
}
EXPORT_SYMBOL(create_syslog_header);
+int dev_vprintk_emit(int level, const struct device *dev,
+ const char *fmt, va_list args)
+{
+ char hdr[128];
+ size_t hdrlen;
+
+ hdrlen = create_syslog_header(dev, hdr, sizeof(hdr));
+
+ return vprintk_emit(0, level, hdrlen ? hdr : NULL, hdrlen, fmt, args);
+}
+EXPORT_SYMBOL(dev_vprintk_emit);
+
+int dev_printk_emit(int level, const struct device *dev, const char *fmt, ...)
+{
+ va_list args;
+ int r;
+
+ va_start(args, fmt);
+
+ r = dev_vprintk_emit(level, dev, fmt, args);
+
+ va_end(args);
+
+ return r;
+}
+EXPORT_SYMBOL(dev_printk_emit);
+
static int __dev_printk(const char *level, const struct device *dev,
struct va_format *vaf)
{
diff --git a/include/linux/device.h b/include/linux/device.h
index 4800d73..0063d01 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -893,6 +893,10 @@ extern const char *dev_driver_string(const struct device *dev);
extern int create_syslog_header(const struct device *dev,
char *hdr, size_t hdrlen);
+extern int dev_vprintk_emit(int level, const struct device *dev,
+ const char *fmt, va_list args);
+extern __printf(3, 4)
+int dev_printk_emit(int level, const struct device *dev, const char *fmt, ...);
extern __printf(3, 4)
int dev_printk(const char *level, const struct device *dev,
@@ -914,6 +918,13 @@ int _dev_info(const struct device *dev, const char *fmt, ...);
#else
+static int dev_vprintk_emit(int level, const struct device *dev,
+ const char *fmt, va_list args)
+{ return 0; }
+static inline __printf(3, 4)
+int dev_printk_emit(int level, const struct device *dev, const char *fmt, ...)
+{ return 0; }
+
static inline int __dev_printk(const char *level, const struct device *dev,
struct va_format *vaf)
{ return 0; }
--
1.7.8.111.gad25c.dirty
^ permalink raw reply related
* [PATCH 5/5] device and dynamic_debug: Use dev_vprintk_emit and dev_printk_emit
From: Joe Perches @ 2012-09-13 3:14 UTC (permalink / raw)
To: Andrew Morton, Greg Kroah-Hartman, Jason Baron
Cc: David S. Miller, Jim Cromie, Kay Sievers, netdev, linux-kernel
In-Reply-To: <cover.1345978012.git.joe@perches.com>
Convert direct calls of vprintk_emit and printk_emit to the
dev_ equivalents.
Make create_syslog_header static.
Signed-off-by: Joe Perches <joe@perches.com>
Acked-by: David S. Miller <davem@davemloft.net>
Tested-by: Jim Cromie <jim.cromie@gmail.com>
Acked-by: Jason Baron <jbaron@redhat.com>
---
drivers/base/core.c | 14 +++++---------
include/linux/device.h | 2 --
lib/dynamic_debug.c | 31 +++++++++++--------------------
net/core/dev.c | 16 ++++++----------
4 files changed, 22 insertions(+), 41 deletions(-)
diff --git a/drivers/base/core.c b/drivers/base/core.c
index ffccb64..65f82e3 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -1861,7 +1861,8 @@ void device_shutdown(void)
*/
#ifdef CONFIG_PRINTK
-int create_syslog_header(const struct device *dev, char *hdr, size_t hdrlen)
+static int
+create_syslog_header(const struct device *dev, char *hdr, size_t hdrlen)
{
const char *subsys;
size_t pos = 0;
@@ -1939,17 +1940,12 @@ EXPORT_SYMBOL(dev_printk_emit);
static int __dev_printk(const char *level, const struct device *dev,
struct va_format *vaf)
{
- char hdr[128];
- size_t hdrlen;
-
if (!dev)
return printk("%s(NULL device *): %pV", level, vaf);
- hdrlen = create_syslog_header(dev, hdr, sizeof(hdr));
-
- return printk_emit(0, level[1] - '0', hdrlen ? hdr : NULL, hdrlen,
- "%s %s: %pV",
- dev_driver_string(dev), dev_name(dev), vaf);
+ return dev_printk_emit(level[1] - '0', dev,
+ "%s %s: %pV",
+ dev_driver_string(dev), dev_name(dev), vaf);
}
int dev_printk(const char *level, const struct device *dev,
diff --git a/include/linux/device.h b/include/linux/device.h
index 0063d01..2da4589 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -891,8 +891,6 @@ extern const char *dev_driver_string(const struct device *dev);
#ifdef CONFIG_PRINTK
-extern int create_syslog_header(const struct device *dev,
- char *hdr, size_t hdrlen);
extern int dev_vprintk_emit(int level, const struct device *dev,
const char *fmt, va_list args);
extern __printf(3, 4)
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c
index 6b3ebab..e7f7d99 100644
--- a/lib/dynamic_debug.c
+++ b/lib/dynamic_debug.c
@@ -591,15 +591,11 @@ int __dynamic_dev_dbg(struct _ddebug *descriptor,
res = printk(KERN_DEBUG "(NULL device *): %pV", &vaf);
} else {
char buf[PREFIX_SIZE];
- char dict[128];
- size_t dictlen;
- dictlen = create_syslog_header(dev, dict, sizeof(dict));
-
- res = printk_emit(0, 7, dictlen ? dict : NULL, dictlen,
- "%s%s %s: %pV",
- dynamic_emit_prefix(descriptor, buf),
- dev_driver_string(dev), dev_name(dev), &vaf);
+ res = dev_printk_emit(7, dev, "%s%s %s: %pV",
+ dynamic_emit_prefix(descriptor, buf),
+ dev_driver_string(dev), dev_name(dev),
+ &vaf);
}
va_end(args);
@@ -627,18 +623,13 @@ int __dynamic_netdev_dbg(struct _ddebug *descriptor,
if (dev && dev->dev.parent) {
char buf[PREFIX_SIZE];
- char dict[128];
- size_t dictlen;
-
- dictlen = create_syslog_header(dev->dev.parent,
- dict, sizeof(dict));
-
- res = printk_emit(0, 7, dictlen ? dict : NULL, dictlen,
- "%s%s %s %s: %pV",
- dynamic_emit_prefix(descriptor, buf),
- dev_driver_string(dev->dev.parent),
- dev_name(dev->dev.parent),
- netdev_name(dev), &vaf);
+
+ res = dev_printk_emit(7, dev->dev.parent,
+ "%s%s %s %s: %pV",
+ dynamic_emit_prefix(descriptor, buf),
+ dev_driver_string(dev->dev.parent),
+ dev_name(dev->dev.parent),
+ netdev_name(dev), &vaf);
} else if (dev) {
res = printk(KERN_DEBUG "%s: %pV", netdev_name(dev), &vaf);
} else {
diff --git a/net/core/dev.c b/net/core/dev.c
index 1ec186a..8ad42fd 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -6428,16 +6428,12 @@ static int __netdev_printk(const char *level, const struct net_device *dev,
int r;
if (dev && dev->dev.parent) {
- char dict[128];
- size_t dictlen = create_syslog_header(dev->dev.parent,
- dict, sizeof(dict));
-
- r = printk_emit(0, level[1] - '0',
- dictlen ? dict : NULL, dictlen,
- "%s %s %s: %pV",
- dev_driver_string(dev->dev.parent),
- dev_name(dev->dev.parent),
- netdev_name(dev), vaf);
+ r = dev_printk_emit(level[1] - '0',
+ dev->dev.parent,
+ "%s %s %s: %pV",
+ dev_driver_string(dev->dev.parent),
+ dev_name(dev->dev.parent),
+ netdev_name(dev), vaf);
} else if (dev) {
r = printk("%s%s: %pV", level, netdev_name(dev), vaf);
} else {
--
1.7.8.111.gad25c.dirty
^ permalink raw reply related
* [PATCH v2 net-next] ipv6: prevent useless neigh alloc on PTP or lo routes
From: Eric Dumazet @ 2012-09-13 3:15 UTC (permalink / raw)
To: David Miller
Cc: netdev, Lorenzo Colitti, Maciej Żenczykowski, Tom Herbert,
Willem de Bruijn
In-Reply-To: <1347505193.13103.1340.camel@edumazet-glaptop>
From: Eric Dumazet <edumazet@google.com>
We have special handling of SIT devices in addrconf_prefix_route()
to avoid allocating a neighbour for each destination.
If routing entry is :
ip -6 route add 2001:db8::/64 dev sit1
Then the kernel will create a new route and neighbour for every new
address under 2001:db8::/64 that we send a packet to
(potentially, 2^64 routes and neighbours).
Under load, we immediately get the infamous "Neighbour table overflow"
message and machine eventually crash.
This does not happen if we specify a next-hop explicitly, like so:
ip -6 route add 2001:db8::/64 via fe80:: dev sit1
Same problem happens if we use routes to loopback.
Idea of this patch is to move existing SIT related code from
addrconf_prefix_route() to a more generic one in ip6_route_add().
This permits ip6_pol_route() to clone route instead of calling
rt6_alloc_cow() and allocate a neighbour.
Many thanks to Lorenzo for his help and suggestions.
Reported-by: Lorenzo Colitti <lorenzo@google.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Maciej Żenczykowski <maze@google.com>
Cc: Tom Herbert <therbert@google.com>
Cc: Willem de Bruijn <willemb@google.com>
---
net/ipv6/addrconf.c | 10 ----------
net/ipv6/route.c | 4 ++++
2 files changed, 4 insertions(+), 10 deletions(-)
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 1237d5d..c6837d2 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -1679,16 +1679,6 @@ addrconf_prefix_route(struct in6_addr *pfx, int plen, struct net_device *dev,
};
cfg.fc_dst = *pfx;
-
- /* Prevent useless cloning on PtP SIT.
- This thing is done here expecting that the whole
- class of non-broadcast devices need not cloning.
- */
-#if defined(CONFIG_IPV6_SIT) || defined(CONFIG_IPV6_SIT_MODULE)
- if (dev->type == ARPHRD_SIT && (dev->flags & IFF_POINTOPOINT))
- cfg.fc_flags |= RTF_NONEXTHOP;
-#endif
-
ip6_route_add(&cfg);
}
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 399613b..7df8dfc 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -1540,6 +1540,10 @@ int ip6_route_add(struct fib6_config *cfg)
} else
rt->rt6i_prefsrc.plen = 0;
+ /* Prevent useless cloning on link types that don't have next hops. */
+ if (dev->flags & (IFF_POINTOPOINT | IFF_LOOPBACK))
+ cfg->fc_flags |= RTF_NONEXTHOP;
+
if (cfg->fc_flags & (RTF_GATEWAY | RTF_NONEXTHOP)) {
err = rt6_bind_neighbour(rt, dev);
if (err)
^ permalink raw reply related
* Re: [REVIEW][PATCH 12/15] userns: Convert drm to use kuid and kgid and struct pid where appropriate
From: Dave Airlie @ 2012-09-13 3:29 UTC (permalink / raw)
To: Eric W. Biederman
Cc: linux-kernel, netdev, linux-fsdevel, Serge E. Hallyn,
David Miller, David Airlie, dri-devel
In-Reply-To: <87ligefz34.fsf@xmission.com>
On Thu, Sep 13, 2012 at 12:14 PM, Eric W. Biederman
<ebiederm@xmission.com> wrote:
> Dave Airlie <airlied@gmail.com> writes:
>
>>> Blink Blink this had not been converted to use struct pid ages ago?
>>>
>>> - On drm open capture the openers kuid and struct pid.
>>> - On drm close release the kuid and struct pid
>>> - When reporting the uid and pid convert the kuid and struct pid
>>> into values in the appropriate namespace.
>>>
>>
>> Hi Eric,
>>
>> I'm fine with this seems okay, do you want me to merge it via
>> drm-next?
>
> My plan is to merge it via my user namespace tree. And since you have
> responed positively I will add your acked-by. There are some nice
> synergies when I get all of the changes in one tree.
>
> If for some reason you want to carry this in your drm tree we can work
> something out.
>
> In this case I expect the change isn't big enough to worry about.
No all fine by me,
for formality sake:
Acked-by: Dave Airlie <airlied@redhat.com>
^ permalink raw reply
* Re: kernel 3.5.2/amd64: iwlwifi 0000:03:00.0: failed to allocate pci memory
From: Marc MERLIN @ 2012-09-13 4:52 UTC (permalink / raw)
To: Johannes Berg; +Cc: wey-yi.w.guy, ilw, linux-wireless, netdev
In-Reply-To: <1347292023.4272.28.camel@jlt4.sipsolutions.net>
[-- Attachment #1: Type: text/plain, Size: 898 bytes --]
On Mon, Sep 10, 2012 at 05:47:03PM +0200, Johannes Berg wrote:
> > but http://p.sipsolutions.net/11ea33b376a5bac5.txt
> > refers to drivers/net/wireless/iwlwifi/dvm/ucode.c
> >
> > Obviously I can fix pathnames by hand, but jus wanted to make sure I'm doing
> > the right thing before doing that.
>
> That'll probably just work. I may also erroneously have included
> dvm16/... changes that are internal only, so you won't have to worry
> about that file.
I had to port the patch back to my 3.5.3 kernel and since then I haven't
hany firmware loading failures, thanks much.
I'll attach the patch below in case it helps others.
Thanks for your help,
Marc
--
"A mouse is a device used to point at the xterm you want to type in" - A.S.R.
Microsoft is to operating systems ....
.... what McDonalds is to gourmet cooking
Home page: http://marc.merlins.org/
[-- Attachment #2: iwlwifi-firmware.patch --]
[-- Type: text/plain, Size: 5010 bytes --]
diff -urN .iwlwifi/iwl-drv.c iwlwifi/iwl-drv.c
--- .iwlwifi/iwl-drv.c 2012-07-21 13:58:29.000000000 -0700
+++ iwlwifi/iwl-drv.c 2012-09-12 16:30:28.997944875 -0700
@@ -116,10 +116,8 @@
static void iwl_free_fw_desc(struct iwl_drv *drv, struct fw_desc *desc)
{
- if (desc->v_addr)
- dma_free_coherent(drv->trans->dev, desc->len,
- desc->v_addr, desc->p_addr);
- desc->v_addr = NULL;
+ vfree(desc->data);
+ desc->data = NULL;
desc->len = 0;
}
@@ -138,21 +136,24 @@
}
static int iwl_alloc_fw_desc(struct iwl_drv *drv, struct fw_desc *desc,
- struct fw_sec *sec)
+ struct fw_sec *sec)
{
- if (!sec || !sec->size) {
- desc->v_addr = NULL;
+ void *data;
+
+ desc->data = NULL;
+
+ if (!sec || !sec->size)
return -EINVAL;
- }
- desc->v_addr = dma_alloc_coherent(drv->trans->dev, sec->size,
- &desc->p_addr, GFP_KERNEL);
- if (!desc->v_addr)
+ data = vmalloc(sec->size);
+ if (!data)
return -ENOMEM;
desc->len = sec->size;
desc->offset = sec->offset;
- memcpy(desc->v_addr, sec->data, sec->size);
+ memcpy(data, sec->data, desc->len);
+ desc->data = data;
+
return 0;
}
diff -urN .iwlwifi/iwl-fw.h iwlwifi/iwl-fw.h
--- .iwlwifi/iwl-fw.h 2012-07-21 13:58:29.000000000 -0700
+++ iwlwifi/iwl-fw.h 2012-09-12 16:30:28.997944875 -0700
@@ -124,8 +124,7 @@
/* one for each uCode image (inst/data, init/runtime/wowlan) */
struct fw_desc {
- dma_addr_t p_addr; /* hardware address */
- void *v_addr; /* software address */
+ const void *data; /* vmalloc'ed data */
u32 len; /* size in bytes */
u32 offset; /* offset in the device */
};
diff -urN .iwlwifi/iwl-trans-pcie.c iwlwifi/iwl-trans-pcie.c
--- .iwlwifi/iwl-trans-pcie.c 2012-07-21 13:58:29.000000000 -0700
+++ iwlwifi/iwl-trans-pcie.c 2012-09-12 16:32:48.190750091 -0700
@@ -896,13 +896,10 @@
/*
* ucode
*/
-static int iwl_load_section(struct iwl_trans *trans, u8 section_num,
- const struct fw_desc *section)
+static int iwl_load_firmware_chunk(struct iwl_trans *trans, u32 dst_addr,
+ dma_addr_t phy_addr, u32 byte_cnt)
{
struct iwl_trans_pcie *trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans);
- dma_addr_t phy_addr = section->p_addr;
- u32 byte_cnt = section->len;
- u32 dst_addr = section->offset;
int ret;
trans_pcie->ucode_write_complete = false;
@@ -915,8 +912,8 @@
FH_SRVC_CHNL_SRAM_ADDR_REG(FH_SRVC_CHNL), dst_addr);
iwl_write_direct32(trans,
- FH_TFDIB_CTRL0_REG(FH_SRVC_CHNL),
- phy_addr & FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK);
+ FH_TFDIB_CTRL0_REG(FH_SRVC_CHNL),
+ phy_addr & FH_MEM_TFDIB_DRAM_ADDR_LSB_MSK);
iwl_write_direct32(trans,
FH_TFDIB_CTRL1_REG(FH_SRVC_CHNL),
@@ -935,19 +932,51 @@
FH_TCSR_TX_CONFIG_REG_VAL_DMA_CREDIT_DISABLE |
FH_TCSR_TX_CONFIG_REG_VAL_CIRQ_HOST_ENDTFD);
- IWL_DEBUG_FW(trans, "[%d] uCode section being loaded...\n",
- section_num);
ret = wait_event_timeout(trans_pcie->ucode_write_waitq,
trans_pcie->ucode_write_complete, 5 * HZ);
if (!ret) {
- IWL_ERR(trans, "Could not load the [%d] uCode section\n",
- section_num);
+ IWL_ERR(trans, "Failed to load firmware chunk!\n");
return -ETIMEDOUT;
}
return 0;
}
+static int iwl_load_section(struct iwl_trans *trans, u8 section_num,
+ const struct fw_desc *section)
+{
+ u8 *v_addr;
+ dma_addr_t p_addr;
+ u32 offset;
+ int ret = 0;
+
+ IWL_DEBUG_FW(trans, "[%d] uCode section being loaded...\n",
+ section_num);
+
+ v_addr = dma_alloc_coherent(trans->dev, PAGE_SIZE, &p_addr, GFP_KERNEL);
+ if (!v_addr)
+ return -ENOMEM;
+
+ for (offset = 0; offset < section->len; offset += PAGE_SIZE) {
+ u32 copy_size;
+
+ copy_size = min_t(u32, PAGE_SIZE, section->len - offset);
+
+ memcpy(v_addr, (u8 *)section->data + offset, copy_size);
+ ret = iwl_load_firmware_chunk(trans, section->offset + offset,
+ p_addr, copy_size);
+ if (ret) {
+ IWL_ERR(trans,
+ "Could not load the [%d] uCode section\n",
+ section_num);
+ break;
+ }
+ }
+
+ dma_free_coherent(trans->dev, PAGE_SIZE, v_addr, p_addr);
+ return ret;
+}
+
static int iwl_load_given_ucode(struct iwl_trans *trans,
const struct fw_img *image)
{
@@ -955,7 +984,7 @@
int i;
for (i = 0; i < IWL_UCODE_SECTION_MAX; i++) {
- if (!image->sec[i].p_addr)
+ if (!image->sec[i].data)
break;
ret = iwl_load_section(trans, i, &image->sec[i]);
diff -urN .iwlwifi/iwl-ucode.c iwlwifi/iwl-ucode.c
--- .iwlwifi/iwl-ucode.c 2012-07-21 13:58:29.000000000 -0700
+++ iwlwifi/iwl-ucode.c 2012-09-12 17:10:18.151765877 -0700
@@ -270,7 +270,7 @@
static int iwl_verify_sec_sparse(struct iwl_priv *priv,
const struct fw_desc *fw_desc)
{
- __le32 *image = (__le32 *)fw_desc->v_addr;
+ __le32 *image = (__le32 *)fw_desc->data;
u32 len = fw_desc->len;
u32 val;
u32 i;
@@ -294,7 +294,7 @@
static void iwl_print_mismatch_sec(struct iwl_priv *priv,
const struct fw_desc *fw_desc)
{
- __le32 *image = (__le32 *)fw_desc->v_addr;
+ __le32 *image = (__le32 *)fw_desc->data;
u32 len = fw_desc->len;
u32 val;
u32 offs;
^ permalink raw reply
* Re: [RFC/RFT 14/15] rtlwifi: Modify files for addition of rtl8723ae
From: Larry Finger @ 2012-09-13 5:36 UTC (permalink / raw)
To: Julian Calaby; +Cc: linville, linux-wireless, netdev, chaoming_li
In-Reply-To: <CAGRGNgWezEzXV0-k6DA7TckNpa=zgN6LNv898N-PRU6P1LYgOw@mail.gmail.com>
On 09/12/2012 10:11 PM, Julian Calaby wrote:
> Hi Larry,
>
> On Thu, Sep 13, 2012 at 6:54 AM, Larry Finger <Larry.Finger@lwfinger.net> wrote:
>> This patch modifies the files of rtlwifi for the addition of a new driver
>> to handle the Realtek RTL8723AE wireless device, and introduces a new
>> routine to maintaim statistics that will be used later for roaming.
>>
>> Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
>> Cc: <chaoming_li@realsil.com.cn>
>> ---
>> drivers/net/wireless/rtlwifi/debug.h | 2 +
>> drivers/net/wireless/rtlwifi/pci.h | 1 +
>> drivers/net/wireless/rtlwifi/stats.c | 274 ++++++++++++++++++++++++++++++++++
>> drivers/net/wireless/rtlwifi/stats.h | 47 ++++++
>> 4 files changed, 324 insertions(+)
>> create mode 100644 drivers/net/wireless/rtlwifi/stats.c
>> create mode 100644 drivers/net/wireless/rtlwifi/stats.h
>>
>> diff --git a/drivers/net/wireless/rtlwifi/debug.h b/drivers/net/wireless/rtlwifi/debug.h
>> index 07493d2..b81e299 100644
>> --- a/drivers/net/wireless/rtlwifi/debug.h
>> +++ b/drivers/net/wireless/rtlwifi/debug.h
>> @@ -106,6 +106,8 @@
>> #define COMP_REGD BIT(27)
>> #define COMP_CHAN BIT(28)
>> #define COMP_USB BIT(29)
>> +#define COMP_EASY_CONCURRENT BIT(29)
>
> Is this supposed to be bit #29 - I notice that COMP_USB is also bit 29.
Yes, that is OK. One will only be used for PCI-based drivers, and the other is
obviously for USB. As nearly all the bits of a 32-bit quantity are used, I
wanted to save one if possible.
In the final version, I'll code this as
#define COMP_USB BIT(29)
#define COMP_EASY_CONCURRENT COMP_USB
That way will be more obvious.
Larry
^ permalink raw reply
* [PATCH net-next 0/4] ipv6: fix the reassembly expire code in nf_conntrack
From: Cong Wang @ 2012-09-13 6:25 UTC (permalink / raw)
To: netdev; +Cc: netfilter-devel, Herbert Xu, David S. Miller, Cong Wang
ipv6: add a new namespace for nf_conntrack_reasm
ipv6: unify conntrack reassembly expire code with
ipv6: make ip6_frag_nqueues() and ip6_frag_mem() static
ipv6: unify fragment thresh handling code
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: "David S. Miller" <davem@davemloft.net>
Signed-off-by: Cong Wang <amwang@redhat.com>
---
include/net/inet_frag.h | 2 +-
include/net/ipv6.h | 32 +++++-
include/net/net_namespace.h | 3 +
include/net/netns/conntrack.h | 6 +
net/ipv4/inet_fragment.c | 9 +-
net/ipv4/ip_fragment.c | 5 +-
net/ipv6/netfilter/nf_conntrack_reasm.c | 196 ++++++++++++++++---------------
net/ipv6/reassembly.c | 88 ++++----------
8 files changed, 176 insertions(+), 165 deletions(-)
^ permalink raw reply
* [PATCH 1/4] ipv6: add a new namespace for nf_conntrack_reasm
From: Cong Wang @ 2012-09-13 6:25 UTC (permalink / raw)
To: netdev
Cc: netfilter-devel, Cong Wang, Herbert Xu, Michal Kubeček,
David Miller, Patrick McHardy, Pablo Neira Ayuso
In-Reply-To: <1347517541-10653-1-git-send-email-amwang@redhat.com>
As pointed by Michal, it is necessary to add a new
namespace for nf_conntrack_reasm code, this prepares
for the second patch.
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: Michal Kubeček <mkubecek@suse.cz>
Cc: David Miller <davem@davemloft.net>
Cc: Patrick McHardy <kaber@trash.net>
Cc: Pablo Neira Ayuso <pablo@netfilter.org>
Cc: netfilter-devel@vger.kernel.org
Signed-off-by: Cong Wang <amwang@redhat.com>
---
include/net/net_namespace.h | 3 +
include/net/netns/conntrack.h | 6 ++
net/ipv6/netfilter/nf_conntrack_reasm.c | 135 +++++++++++++++++++++----------
3 files changed, 102 insertions(+), 42 deletions(-)
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
index 5ae57f1..5c467bb 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -93,6 +93,9 @@ struct net {
#if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
struct netns_ct ct;
#endif
+#if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
+ struct netns_nf_ct nf_ct;
+#endif
struct sock *nfnl;
struct sock *nfnl_stash;
#endif
diff --git a/include/net/netns/conntrack.h b/include/net/netns/conntrack.h
index a1d83cc..13503be 100644
--- a/include/net/netns/conntrack.h
+++ b/include/net/netns/conntrack.h
@@ -96,4 +96,10 @@ struct netns_ct {
#endif
char *slabname;
};
+
+struct netns_nf_ct {
+ struct netns_sysctl_ipv6 sysctl;
+ struct netns_frags frags;
+};
+
#endif
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index f94fb3a..fff5b71 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -71,27 +71,26 @@ struct nf_ct_frag6_queue
};
static struct inet_frags nf_frags;
-static struct netns_frags nf_init_frags;
#ifdef CONFIG_SYSCTL
static struct ctl_table nf_ct_frag6_sysctl_table[] = {
{
.procname = "nf_conntrack_frag6_timeout",
- .data = &nf_init_frags.timeout,
+ .data = &init_net.nf_ct.frags.timeout,
.maxlen = sizeof(unsigned int),
.mode = 0644,
.proc_handler = proc_dointvec_jiffies,
},
{
.procname = "nf_conntrack_frag6_low_thresh",
- .data = &nf_init_frags.low_thresh,
+ .data = &init_net.nf_ct.frags.low_thresh,
.maxlen = sizeof(unsigned int),
.mode = 0644,
.proc_handler = proc_dointvec,
},
{
.procname = "nf_conntrack_frag6_high_thresh",
- .data = &nf_init_frags.high_thresh,
+ .data = &init_net.nf_ct.frags.high_thresh,
.maxlen = sizeof(unsigned int),
.mode = 0644,
.proc_handler = proc_dointvec,
@@ -99,7 +98,54 @@ static struct ctl_table nf_ct_frag6_sysctl_table[] = {
{ }
};
-static struct ctl_table_header *nf_ct_frag6_sysctl_header;
+static int __net_init nf_ct_frag6_sysctl_register(struct net *net)
+{
+ struct ctl_table *table;
+ struct ctl_table_header *hdr;
+
+ table = nf_ct_frag6_sysctl_table;
+ if (!net_eq(net, &init_net)) {
+ table = kmemdup(table, sizeof(nf_ct_frag6_sysctl_table), GFP_KERNEL);
+ if (table == NULL)
+ goto err_alloc;
+
+ table[0].data = &net->ipv6.frags.high_thresh;
+ table[1].data = &net->ipv6.frags.low_thresh;
+ table[2].data = &net->ipv6.frags.timeout;
+ }
+
+ hdr = register_net_sysctl(net, "net/netfilter", table);
+ if (hdr == NULL)
+ goto err_reg;
+
+ net->ipv6.sysctl.frags_hdr = hdr;
+ return 0;
+
+err_reg:
+ if (!net_eq(net, &init_net))
+ kfree(table);
+err_alloc:
+ return -ENOMEM;
+}
+
+static void __net_exit nf_ct_frags6_sysctl_unregister(struct net *net)
+{
+ struct ctl_table *table;
+
+ table = net->nf_ct.sysctl.frags_hdr->ctl_table_arg;
+ unregister_net_sysctl_table(net->nf_ct.sysctl.frags_hdr);
+ if (!net_eq(net, &init_net))
+ kfree(table);
+}
+
+#else
+static int __net_init nf_ct_frag6_sysctl_register(struct net *net)
+{
+ return 0;
+}
+static void __net_exit nf_ct_frags6_sysctl_unregister(struct net *net)
+{
+}
#endif
static unsigned int nf_hashfn(struct inet_frag_queue *q)
@@ -131,13 +177,6 @@ static __inline__ void fq_kill(struct nf_ct_frag6_queue *fq)
inet_frag_kill(&fq->q, &nf_frags);
}
-static void nf_ct_frag6_evictor(void)
-{
- local_bh_disable();
- inet_frag_evictor(&nf_init_frags, &nf_frags);
- local_bh_enable();
-}
-
static void nf_ct_frag6_expire(unsigned long data)
{
struct nf_ct_frag6_queue *fq;
@@ -159,8 +198,8 @@ out:
/* Creation primitives. */
-static __inline__ struct nf_ct_frag6_queue *
-fq_find(__be32 id, u32 user, struct in6_addr *src, struct in6_addr *dst)
+static __inline__ struct nf_ct_frag6_queue*
+fq_find(struct net *net, __be32 id, u32 user, struct in6_addr *src, struct in6_addr *dst)
{
struct inet_frag_queue *q;
struct ip6_create_arg arg;
@@ -174,7 +213,7 @@ fq_find(__be32 id, u32 user, struct in6_addr *src, struct in6_addr *dst)
read_lock_bh(&nf_frags.lock);
hash = inet6_hash_frag(id, src, dst, nf_frags.rnd);
- q = inet_frag_find(&nf_init_frags, &nf_frags, &arg, hash);
+ q = inet_frag_find(&net->nf_ct.frags, &nf_frags, &arg, hash);
local_bh_enable();
if (q == NULL)
goto oom;
@@ -186,7 +225,7 @@ oom:
}
-static int nf_ct_frag6_queue(struct nf_ct_frag6_queue *fq, struct sk_buff *skb,
+static int nf_ct_frag6_queue(struct nf_ct_frag6_queue*fq, struct sk_buff *skb,
const struct frag_hdr *fhdr, int nhoff)
{
struct sk_buff *prev, *next;
@@ -312,7 +351,7 @@ found:
fq->q.meat += skb->len;
if (payload_len > fq->q.max_size)
fq->q.max_size = payload_len;
- atomic_add(skb->truesize, &nf_init_frags.mem);
+ atomic_add(skb->truesize, &fq->q.net->mem);
/* The first fragment.
* nhoffset is obtained from the first fragment, of course.
@@ -322,7 +361,7 @@ found:
fq->q.last_in |= INET_FRAG_FIRST_IN;
}
write_lock(&nf_frags.lock);
- list_move_tail(&fq->q.lru_list, &nf_init_frags.lru_list);
+ list_move_tail(&fq->q.lru_list, &fq->q.net->lru_list);
write_unlock(&nf_frags.lock);
return 0;
@@ -391,7 +430,7 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
clone->ip_summed = head->ip_summed;
NFCT_FRAG6_CB(clone)->orig = NULL;
- atomic_add(clone->truesize, &nf_init_frags.mem);
+ atomic_add(clone->truesize, &fq->q.net->mem);
}
/* We have to remove fragment header from datagram and to relocate
@@ -415,7 +454,7 @@ nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
head->csum = csum_add(head->csum, fp->csum);
head->truesize += fp->truesize;
}
- atomic_sub(head->truesize, &nf_init_frags.mem);
+ atomic_sub(head->truesize, &fq->q.net->mem);
head->local_df = 1;
head->next = NULL;
@@ -527,6 +566,7 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user)
{
struct sk_buff *clone;
struct net_device *dev = skb->dev;
+ struct net *net = skb_dst(skb) ? dev_net(skb_dst(skb)->dev) : dev_net(skb->dev);
struct frag_hdr *fhdr;
struct nf_ct_frag6_queue *fq;
struct ipv6hdr *hdr;
@@ -560,10 +600,13 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user)
hdr = ipv6_hdr(clone);
fhdr = (struct frag_hdr *)skb_transport_header(clone);
- if (atomic_read(&nf_init_frags.mem) > nf_init_frags.high_thresh)
- nf_ct_frag6_evictor();
+ if (atomic_read(&net->nf_ct.frags.mem) > net->nf_ct.frags.high_thresh) {
+ local_bh_disable();
+ inet_frag_evictor(&net->nf_ct.frags, &nf_frags);
+ local_bh_enable();
+ }
- fq = fq_find(fhdr->identification, user, &hdr->saddr, &hdr->daddr);
+ fq = fq_find(net, fhdr->identification, user, &hdr->saddr, &hdr->daddr);
if (fq == NULL) {
pr_debug("Can't find and can't create new queue\n");
goto ret_orig;
@@ -621,8 +664,31 @@ void nf_ct_frag6_output(unsigned int hooknum, struct sk_buff *skb,
nf_conntrack_put_reasm(skb);
}
+static int nf_ct_net_init(struct net *net)
+{
+ net->nf_ct.frags.high_thresh = IPV6_FRAG_HIGH_THRESH;
+ net->nf_ct.frags.low_thresh = IPV6_FRAG_LOW_THRESH;
+ net->nf_ct.frags.timeout = IPV6_FRAG_TIMEOUT;
+ inet_frags_init_net(&net->nf_ct.frags);
+
+ return nf_ct_frag6_sysctl_register(net);
+}
+
+static void nf_ct_net_exit(struct net *net)
+{
+ nf_ct_frags6_sysctl_unregister(net);
+ inet_frags_exit_net(&net->nf_ct.frags, &nf_frags);
+}
+
+static struct pernet_operations nf_ct_net_ops = {
+ .init = nf_ct_net_init,
+ .exit = nf_ct_net_exit,
+};
+
int nf_ct_frag6_init(void)
{
+ int ret = 0;
+
nf_frags.hashfn = nf_hashfn;
nf_frags.constructor = ip6_frag_init;
nf_frags.destructor = NULL;
@@ -631,32 +697,17 @@ int nf_ct_frag6_init(void)
nf_frags.match = ip6_frag_match;
nf_frags.frag_expire = nf_ct_frag6_expire;
nf_frags.secret_interval = 10 * 60 * HZ;
- nf_init_frags.timeout = IPV6_FRAG_TIMEOUT;
- nf_init_frags.high_thresh = IPV6_FRAG_HIGH_THRESH;
- nf_init_frags.low_thresh = IPV6_FRAG_LOW_THRESH;
- inet_frags_init_net(&nf_init_frags);
inet_frags_init(&nf_frags);
-#ifdef CONFIG_SYSCTL
- nf_ct_frag6_sysctl_header = register_net_sysctl(&init_net, "net/netfilter",
- nf_ct_frag6_sysctl_table);
- if (!nf_ct_frag6_sysctl_header) {
+ ret = register_pernet_subsys(&nf_ct_net_ops);
+ if (ret)
inet_frags_fini(&nf_frags);
- return -ENOMEM;
- }
-#endif
- return 0;
+ return ret;
}
void nf_ct_frag6_cleanup(void)
{
-#ifdef CONFIG_SYSCTL
- unregister_net_sysctl_table(nf_ct_frag6_sysctl_header);
- nf_ct_frag6_sysctl_header = NULL;
-#endif
+ unregister_pernet_subsys(&nf_ct_net_ops);
inet_frags_fini(&nf_frags);
-
- nf_init_frags.low_thresh = 0;
- nf_ct_frag6_evictor();
}
--
1.7.7.6
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 2/4] ipv6: unify conntrack reassembly expire code with standard one
From: Cong Wang @ 2012-09-13 6:25 UTC (permalink / raw)
To: netdev
Cc: netfilter-devel, Cong Wang, Herbert Xu, Michal Kubeček,
David Miller, Hideaki YOSHIFUJI, Patrick McHardy,
Pablo Neira Ayuso
In-Reply-To: <1347517541-10653-1-git-send-email-amwang@redhat.com>
Two years ago, Shan Wei tried to fix this:
http://patchwork.ozlabs.org/patch/43905/
The problem is that RFC2460 requires an ICMP Time
Exceeded -- Fragment Reassembly Time Exceeded message should be
sent to the source of that fragment, if the defragmentation
times out.
"
If insufficient fragments are received to complete reassembly of a
packet within 60 seconds of the reception of the first-arriving
fragment of that packet, reassembly of that packet must be
abandoned and all the fragments that have been received for that
packet must be discarded. If the first fragment (i.e., the one
with a Fragment Offset of zero) has been received, an ICMP Time
Exceeded -- Fragment Reassembly Time Exceeded message should be
sent to the source of that fragment.
"
As Herbert suggested, we could actually use the standard IPv6
reassembly code which follows RFC2460.
With this patch applied, I can see ICMP Time Exceeded sent
from the receiver when the sender sent out 3/4 fragmented
IPv6 UPD packet.
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: Michal Kubeček <mkubecek@suse.cz>
Cc: David Miller <davem@davemloft.net>
Cc: Hideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>
Cc: Patrick McHardy <kaber@trash.net>
Cc: Pablo Neira Ayuso <pablo@netfilter.org>
Cc: netfilter-devel@vger.kernel.org
Signed-off-by: Cong Wang <amwang@redhat.com>
---
include/net/ipv6.h | 19 ++++++++
net/ipv6/netfilter/nf_conntrack_reasm.c | 71 +++++++-----------------------
net/ipv6/reassembly.c | 62 ++++++++-------------------
3 files changed, 54 insertions(+), 98 deletions(-)
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 9bed5d4..81d4455 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -411,6 +411,25 @@ struct ip6_create_arg {
void ip6_frag_init(struct inet_frag_queue *q, void *a);
bool ip6_frag_match(struct inet_frag_queue *q, void *a);
+/*
+ * Equivalent of ipv4 struct ip
+ */
+struct frag_queue {
+ struct inet_frag_queue q;
+
+ __be32 id; /* fragment id */
+ u32 user;
+ struct in6_addr saddr;
+ struct in6_addr daddr;
+
+ int iif;
+ unsigned int csum;
+ __u16 nhoffset;
+};
+
+void ip6_expire_frag_queue(struct net *net, struct frag_queue *fq,
+ struct inet_frags *frags);
+
static inline bool ipv6_addr_any(const struct in6_addr *a)
{
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index fff5b71..ecefb31 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -57,19 +57,6 @@ struct nf_ct_frag6_skb_cb
#define NFCT_FRAG6_CB(skb) ((struct nf_ct_frag6_skb_cb*)((skb)->cb))
-struct nf_ct_frag6_queue
-{
- struct inet_frag_queue q;
-
- __be32 id; /* fragment id */
- u32 user;
- struct in6_addr saddr;
- struct in6_addr daddr;
-
- unsigned int csum;
- __u16 nhoffset;
-};
-
static struct inet_frags nf_frags;
#ifdef CONFIG_SYSCTL
@@ -150,9 +137,9 @@ static void __net_exit nf_ct_frags6_sysctl_unregister(struct net *net)
static unsigned int nf_hashfn(struct inet_frag_queue *q)
{
- const struct nf_ct_frag6_queue *nq;
+ const struct frag_queue *nq;
- nq = container_of(q, struct nf_ct_frag6_queue, q);
+ nq = container_of(q, struct frag_queue, q);
return inet6_hash_frag(nq->id, &nq->saddr, &nq->daddr, nf_frags.rnd);
}
@@ -162,43 +149,19 @@ static void nf_skb_free(struct sk_buff *skb)
kfree_skb(NFCT_FRAG6_CB(skb)->orig);
}
-/* Destruction primitives. */
-
-static __inline__ void fq_put(struct nf_ct_frag6_queue *fq)
-{
- inet_frag_put(&fq->q, &nf_frags);
-}
-
-/* Kill fq entry. It is not destroyed immediately,
- * because caller (and someone more) holds reference count.
- */
-static __inline__ void fq_kill(struct nf_ct_frag6_queue *fq)
-{
- inet_frag_kill(&fq->q, &nf_frags);
-}
-
static void nf_ct_frag6_expire(unsigned long data)
{
- struct nf_ct_frag6_queue *fq;
-
- fq = container_of((struct inet_frag_queue *)data,
- struct nf_ct_frag6_queue, q);
-
- spin_lock(&fq->q.lock);
+ struct frag_queue *fq;
+ struct net *net;
- if (fq->q.last_in & INET_FRAG_COMPLETE)
- goto out;
+ fq = container_of((struct inet_frag_queue *)data, struct frag_queue, q);
+ net = container_of(fq->q.net, struct net, nf_ct.frags);
- fq_kill(fq);
-
-out:
- spin_unlock(&fq->q.lock);
- fq_put(fq);
+ ip6_expire_frag_queue(net, fq, &nf_frags);
}
/* Creation primitives. */
-
-static __inline__ struct nf_ct_frag6_queue*
+static __inline__ struct frag_queue *
fq_find(struct net *net, __be32 id, u32 user, struct in6_addr *src, struct in6_addr *dst)
{
struct inet_frag_queue *q;
@@ -218,14 +181,14 @@ fq_find(struct net *net, __be32 id, u32 user, struct in6_addr *src, struct in6_a
if (q == NULL)
goto oom;
- return container_of(q, struct nf_ct_frag6_queue, q);
+ return container_of(q, struct frag_queue, q);
oom:
return NULL;
}
-static int nf_ct_frag6_queue(struct nf_ct_frag6_queue*fq, struct sk_buff *skb,
+static int nf_ct_frag6_queue(struct frag_queue *fq, struct sk_buff *skb,
const struct frag_hdr *fhdr, int nhoff)
{
struct sk_buff *prev, *next;
@@ -366,7 +329,7 @@ found:
return 0;
discard_fq:
- fq_kill(fq);
+ inet_frag_kill(&fq->q, &nf_frags);
err:
return -1;
}
@@ -381,12 +344,12 @@ err:
* the last and the first frames arrived and all the bits are here.
*/
static struct sk_buff *
-nf_ct_frag6_reasm(struct nf_ct_frag6_queue *fq, struct net_device *dev)
+nf_ct_frag6_reasm(struct frag_queue *fq, struct net_device *dev)
{
struct sk_buff *fp, *op, *head = fq->q.fragments;
int payload_len;
- fq_kill(fq);
+ inet_frag_kill(&fq->q, &nf_frags);
WARN_ON(head == NULL);
WARN_ON(NFCT_FRAG6_CB(head)->offset != 0);
@@ -568,7 +531,7 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user)
struct net_device *dev = skb->dev;
struct net *net = skb_dst(skb) ? dev_net(skb_dst(skb)->dev) : dev_net(skb->dev);
struct frag_hdr *fhdr;
- struct nf_ct_frag6_queue *fq;
+ struct frag_queue *fq;
struct ipv6hdr *hdr;
int fhoff, nhoff;
u8 prevhdr;
@@ -617,7 +580,7 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user)
if (nf_ct_frag6_queue(fq, clone, fhdr, nhoff) < 0) {
spin_unlock_bh(&fq->q.lock);
pr_debug("Can't insert skb to queue\n");
- fq_put(fq);
+ inet_frag_put(&fq->q, &nf_frags);
goto ret_orig;
}
@@ -629,7 +592,7 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user)
}
spin_unlock_bh(&fq->q.lock);
- fq_put(fq);
+ inet_frag_put(&fq->q, &nf_frags);
return ret_skb;
ret_orig:
@@ -693,7 +656,7 @@ int nf_ct_frag6_init(void)
nf_frags.constructor = ip6_frag_init;
nf_frags.destructor = NULL;
nf_frags.skb_free = nf_skb_free;
- nf_frags.qsize = sizeof(struct nf_ct_frag6_queue);
+ nf_frags.qsize = sizeof(struct frag_queue);
nf_frags.match = ip6_frag_match;
nf_frags.frag_expire = nf_ct_frag6_expire;
nf_frags.secret_interval = 10 * 60 * HZ;
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 4ff9af6..8508c8c 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -65,24 +65,6 @@ struct ip6frag_skb_cb
#define FRAG6_CB(skb) ((struct ip6frag_skb_cb*)((skb)->cb))
-/*
- * Equivalent of ipv4 struct ipq
- */
-
-struct frag_queue
-{
- struct inet_frag_queue q;
-
- __be32 id; /* fragment id */
- u32 user;
- struct in6_addr saddr;
- struct in6_addr daddr;
-
- int iif;
- unsigned int csum;
- __u16 nhoffset;
-};
-
static struct inet_frags ip6_frags;
int ip6_frag_nqueues(struct net *net)
@@ -159,21 +141,6 @@ void ip6_frag_init(struct inet_frag_queue *q, void *a)
}
EXPORT_SYMBOL(ip6_frag_init);
-/* Destruction primitives. */
-
-static __inline__ void fq_put(struct frag_queue *fq)
-{
- inet_frag_put(&fq->q, &ip6_frags);
-}
-
-/* Kill fq entry. It is not destroyed immediately,
- * because caller (and someone more) holds reference count.
- */
-static __inline__ void fq_kill(struct frag_queue *fq)
-{
- inet_frag_kill(&fq->q, &ip6_frags);
-}
-
static void ip6_evictor(struct net *net, struct inet6_dev *idev)
{
int evicted;
@@ -183,22 +150,17 @@ static void ip6_evictor(struct net *net, struct inet6_dev *idev)
IP6_ADD_STATS_BH(net, idev, IPSTATS_MIB_REASMFAILS, evicted);
}
-static void ip6_frag_expire(unsigned long data)
+void ip6_expire_frag_queue(struct net *net, struct frag_queue *fq, struct inet_frags *frags)
{
- struct frag_queue *fq;
struct net_device *dev = NULL;
- struct net *net;
-
- fq = container_of((struct inet_frag_queue *)data, struct frag_queue, q);
spin_lock(&fq->q.lock);
if (fq->q.last_in & INET_FRAG_COMPLETE)
goto out;
- fq_kill(fq);
+ inet_frag_kill(&fq->q, frags);
- net = container_of(fq->q.net, struct net, ipv6.frags);
rcu_read_lock();
dev = dev_get_by_index_rcu(net, fq->iif);
if (!dev)
@@ -222,7 +184,19 @@ out_rcu_unlock:
rcu_read_unlock();
out:
spin_unlock(&fq->q.lock);
- fq_put(fq);
+ inet_frag_put(&fq->q, frags);
+}
+EXPORT_SYMBOL(ip6_expire_frag_queue);
+
+static void ip6_frag_expire(unsigned long data)
+{
+ struct frag_queue *fq;
+ struct net *net;
+
+ fq = container_of((struct inet_frag_queue *)data, struct frag_queue, q);
+ net = container_of(fq->q.net, struct net, ipv6.frags);
+
+ ip6_expire_frag_queue(net, fq, &ip6_frags);
}
static __inline__ struct frag_queue *
@@ -391,7 +365,7 @@ found:
return -1;
discard_fq:
- fq_kill(fq);
+ inet_frag_kill(&fq->q, &ip6_frags);
err:
IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)),
IPSTATS_MIB_REASMFAILS);
@@ -417,7 +391,7 @@ static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev,
unsigned int nhoff;
int sum_truesize;
- fq_kill(fq);
+ inet_frag_kill(&fq->q, &ip6_frags);
/* Make the one we just received the head. */
if (prev) {
@@ -586,7 +560,7 @@ static int ipv6_frag_rcv(struct sk_buff *skb)
ret = ip6_frag_queue(fq, skb, fhdr, IP6CB(skb)->nhoff);
spin_unlock(&fq->q.lock);
- fq_put(fq);
+ inet_frag_put(&fq->q, &ip6_frags);
return ret;
}
--
1.7.7.6
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 4/4] ipv6: unify fragment thresh handling code
From: Cong Wang @ 2012-09-13 6:25 UTC (permalink / raw)
To: netdev
Cc: netfilter-devel, Cong Wang, Herbert Xu, Michal Kubeček,
David Miller
In-Reply-To: <1347517541-10653-1-git-send-email-amwang@redhat.com>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: Michal Kubeček <mkubecek@suse.cz>
Cc: David Miller <davem@davemloft.net>
Signed-off-by: Cong Wang <amwang@redhat.com>
---
include/net/inet_frag.h | 2 +-
net/ipv4/inet_fragment.c | 9 +++++++--
net/ipv4/ip_fragment.c | 5 ++---
net/ipv6/netfilter/nf_conntrack_reasm.c | 8 +++-----
net/ipv6/reassembly.c | 16 +++++-----------
5 files changed, 18 insertions(+), 22 deletions(-)
diff --git a/include/net/inet_frag.h b/include/net/inet_frag.h
index 5098ee7..32786a0 100644
--- a/include/net/inet_frag.h
+++ b/include/net/inet_frag.h
@@ -61,7 +61,7 @@ void inet_frags_exit_net(struct netns_frags *nf, struct inet_frags *f);
void inet_frag_kill(struct inet_frag_queue *q, struct inet_frags *f);
void inet_frag_destroy(struct inet_frag_queue *q,
struct inet_frags *f, int *work);
-int inet_frag_evictor(struct netns_frags *nf, struct inet_frags *f);
+int inet_frag_evictor(struct netns_frags *nf, struct inet_frags *f, bool force);
struct inet_frag_queue *inet_frag_find(struct netns_frags *nf,
struct inet_frags *f, void *key, unsigned int hash)
__releases(&f->lock);
diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c
index 85190e6..4750d2b 100644
--- a/net/ipv4/inet_fragment.c
+++ b/net/ipv4/inet_fragment.c
@@ -89,7 +89,7 @@ void inet_frags_exit_net(struct netns_frags *nf, struct inet_frags *f)
nf->low_thresh = 0;
local_bh_disable();
- inet_frag_evictor(nf, f);
+ inet_frag_evictor(nf, f, true);
local_bh_enable();
}
EXPORT_SYMBOL(inet_frags_exit_net);
@@ -158,11 +158,16 @@ void inet_frag_destroy(struct inet_frag_queue *q, struct inet_frags *f,
}
EXPORT_SYMBOL(inet_frag_destroy);
-int inet_frag_evictor(struct netns_frags *nf, struct inet_frags *f)
+int inet_frag_evictor(struct netns_frags *nf, struct inet_frags *f, bool force)
{
struct inet_frag_queue *q;
int work, evicted = 0;
+ if (!force) {
+ if (atomic_read(&nf->mem) <= nf->high_thresh)
+ return 0;
+ }
+
work = atomic_read(&nf->mem) - nf->low_thresh;
while (work > 0) {
read_lock(&f->lock);
diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c
index fa6a12c..448e685 100644
--- a/net/ipv4/ip_fragment.c
+++ b/net/ipv4/ip_fragment.c
@@ -219,7 +219,7 @@ static void ip_evictor(struct net *net)
{
int evicted;
- evicted = inet_frag_evictor(&net->ipv4.frags, &ip4_frags);
+ evicted = inet_frag_evictor(&net->ipv4.frags, &ip4_frags, false);
if (evicted)
IP_ADD_STATS_BH(net, IPSTATS_MIB_REASMFAILS, evicted);
}
@@ -684,8 +684,7 @@ int ip_defrag(struct sk_buff *skb, u32 user)
IP_INC_STATS_BH(net, IPSTATS_MIB_REASMREQDS);
/* Start by cleaning up the memory. */
- if (atomic_read(&net->ipv4.frags.mem) > net->ipv4.frags.high_thresh)
- ip_evictor(net);
+ ip_evictor(net);
/* Lookup (or create) queue header */
if ((qp = ip_find(net, ip_hdr(skb), user)) != NULL) {
diff --git a/net/ipv6/netfilter/nf_conntrack_reasm.c b/net/ipv6/netfilter/nf_conntrack_reasm.c
index ecefb31..22e9e55 100644
--- a/net/ipv6/netfilter/nf_conntrack_reasm.c
+++ b/net/ipv6/netfilter/nf_conntrack_reasm.c
@@ -563,11 +563,9 @@ struct sk_buff *nf_ct_frag6_gather(struct sk_buff *skb, u32 user)
hdr = ipv6_hdr(clone);
fhdr = (struct frag_hdr *)skb_transport_header(clone);
- if (atomic_read(&net->nf_ct.frags.mem) > net->nf_ct.frags.high_thresh) {
- local_bh_disable();
- inet_frag_evictor(&net->nf_ct.frags, &nf_frags);
- local_bh_enable();
- }
+ local_bh_disable();
+ inet_frag_evictor(&net->nf_ct.frags, &nf_frags, false);
+ local_bh_enable();
fq = fq_find(net, fhdr->identification, user, &hdr->saddr, &hdr->daddr);
if (fq == NULL) {
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index cac690c..a1610ac 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -131,15 +131,6 @@ void ip6_frag_init(struct inet_frag_queue *q, void *a)
}
EXPORT_SYMBOL(ip6_frag_init);
-static void ip6_evictor(struct net *net, struct inet6_dev *idev)
-{
- int evicted;
-
- evicted = inet_frag_evictor(&net->ipv6.frags, &ip6_frags);
- if (evicted)
- IP6_ADD_STATS_BH(net, idev, IPSTATS_MIB_REASMFAILS, evicted);
-}
-
void ip6_expire_frag_queue(struct net *net, struct frag_queue *fq, struct inet_frags *frags)
{
struct net_device *dev = NULL;
@@ -514,6 +505,7 @@ static int ipv6_frag_rcv(struct sk_buff *skb)
struct frag_queue *fq;
const struct ipv6hdr *hdr = ipv6_hdr(skb);
struct net *net = dev_net(skb_dst(skb)->dev);
+ int evicted;
IP6_INC_STATS_BH(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_REASMREQDS);
@@ -538,8 +530,10 @@ static int ipv6_frag_rcv(struct sk_buff *skb)
return 1;
}
- if (atomic_read(&net->ipv6.frags.mem) > net->ipv6.frags.high_thresh)
- ip6_evictor(net, ip6_dst_idev(skb_dst(skb)));
+ evicted = inet_frag_evictor(&net->ipv6.frags, &ip6_frags, false);
+ if (evicted)
+ IP6_ADD_STATS_BH(net, ip6_dst_idev(skb_dst(skb)),
+ IPSTATS_MIB_REASMFAILS, evicted);
fq = fq_find(net, fhdr->identification, &hdr->saddr, &hdr->daddr);
if (fq != NULL) {
--
1.7.7.6
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 3/4] ipv6: make ip6_frag_nqueues() and ip6_frag_mem() static inline
From: Cong Wang @ 2012-09-13 6:25 UTC (permalink / raw)
To: netdev
Cc: netfilter-devel, Cong Wang, Herbert Xu, Michal Kubeček,
David Miller
In-Reply-To: <1347517541-10653-1-git-send-email-amwang@redhat.com>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: Michal Kubeček <mkubecek@suse.cz>
Cc: David Miller <davem@davemloft.net>
Signed-off-by: Cong Wang <amwang@redhat.com>
---
include/net/ipv6.h | 13 +++++++++++--
net/ipv6/reassembly.c | 10 ----------
2 files changed, 11 insertions(+), 12 deletions(-)
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 81d4455..ec73f6c 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -271,8 +271,17 @@ struct ipv6_txoptions *ipv6_fixup_options(struct ipv6_txoptions *opt_space,
extern bool ipv6_opt_accepted(const struct sock *sk, const struct sk_buff *skb);
-int ip6_frag_nqueues(struct net *net);
-int ip6_frag_mem(struct net *net);
+#ifdef CONFIG_IPV6
+static inline int ip6_frag_nqueues(struct net *net)
+{
+ return net->ipv6.frags.nqueues;
+}
+
+static inline int ip6_frag_mem(struct net *net)
+{
+ return atomic_read(&net->ipv6.frags.mem);
+}
+#endif
#define IPV6_FRAG_HIGH_THRESH (256 * 1024) /* 262144 */
#define IPV6_FRAG_LOW_THRESH (192 * 1024) /* 196608 */
diff --git a/net/ipv6/reassembly.c b/net/ipv6/reassembly.c
index 8508c8c..cac690c 100644
--- a/net/ipv6/reassembly.c
+++ b/net/ipv6/reassembly.c
@@ -67,16 +67,6 @@ struct ip6frag_skb_cb
static struct inet_frags ip6_frags;
-int ip6_frag_nqueues(struct net *net)
-{
- return net->ipv6.frags.nqueues;
-}
-
-int ip6_frag_mem(struct net *net)
-{
- return atomic_read(&net->ipv6.frags.mem);
-}
-
static int ip6_frag_reasm(struct frag_queue *fq, struct sk_buff *prev,
struct net_device *dev);
--
1.7.7.6
^ permalink raw reply related
* [v3 PATCH 1/2] netprio_cgroup: Remove update_netdev_tables() since it is unnecessary
From: Srivatsa S. Bhat @ 2012-09-13 6:32 UTC (permalink / raw)
To: davem, nhorman
Cc: David.Laight, john.r.fastabend, gaofeng, eric.dumazet,
mark.d.rustad, lizefan, netdev, linux-kernel, Srivatsa S. Bhat
The update_netdev_tables() function appears to be unnecessary, since the
write_update_netdev_table() function will adjust the priomaps as and when
required anyway. So drop the usage of update_netdev_tables() entirely.
Signed-off-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
---
net/core/netprio_cgroup.c | 32 --------------------------------
1 files changed, 0 insertions(+), 32 deletions(-)
diff --git a/net/core/netprio_cgroup.c b/net/core/netprio_cgroup.c
index c75e3f9..fd339bb0 100644
--- a/net/core/netprio_cgroup.c
+++ b/net/core/netprio_cgroup.c
@@ -109,32 +109,6 @@ static int write_update_netdev_table(struct net_device *dev)
return ret;
}
-static int update_netdev_tables(void)
-{
- int ret = 0;
- struct net_device *dev;
- u32 max_len;
- struct netprio_map *map;
-
- rtnl_lock();
- max_len = atomic_read(&max_prioidx) + 1;
- for_each_netdev(&init_net, dev) {
- map = rtnl_dereference(dev->priomap);
- /*
- * don't allocate priomap if we didn't
- * change net_prio.ifpriomap (map == NULL),
- * this will speed up skb_update_prio.
- */
- if (map && map->priomap_len < max_len) {
- ret = extend_netdev_table(dev, max_len);
- if (ret < 0)
- break;
- }
- }
- rtnl_unlock();
- return ret;
-}
-
static struct cgroup_subsys_state *cgrp_create(struct cgroup *cgrp)
{
struct cgroup_netprio_state *cs;
@@ -153,12 +127,6 @@ static struct cgroup_subsys_state *cgrp_create(struct cgroup *cgrp)
goto out;
}
- ret = update_netdev_tables();
- if (ret < 0) {
- put_prioidx(cs->prioidx);
- goto out;
- }
-
return &cs->css;
out:
kfree(cs);
^ permalink raw reply related
* [v3 PATCH 2/2] netprio_cgroup: Use memcpy instead of the for-loop to copy priomap
From: Srivatsa S. Bhat @ 2012-09-13 6:32 UTC (permalink / raw)
To: davem, nhorman
Cc: David.Laight, john.r.fastabend, gaofeng, eric.dumazet,
mark.d.rustad, lizefan, netdev, linux-kernel, Srivatsa S. Bhat
In-Reply-To: <20120913063225.6278.87780.stgit@srivatsabhat.in.ibm.com>
Replace the current (inefficient) for-loop with memcpy, to copy priomap.
Signed-off-by: Srivatsa S. Bhat <srivatsa.bhat@linux.vnet.ibm.com>
---
net/core/netprio_cgroup.c | 9 ++++-----
1 files changed, 4 insertions(+), 5 deletions(-)
diff --git a/net/core/netprio_cgroup.c b/net/core/netprio_cgroup.c
index fd339bb0..45c503e 100644
--- a/net/core/netprio_cgroup.c
+++ b/net/core/netprio_cgroup.c
@@ -73,7 +73,6 @@ static int extend_netdev_table(struct net_device *dev, u32 new_len)
((sizeof(u32) * new_len));
struct netprio_map *new_priomap = kzalloc(new_size, GFP_KERNEL);
struct netprio_map *old_priomap;
- int i;
old_priomap = rtnl_dereference(dev->priomap);
@@ -82,10 +81,10 @@ static int extend_netdev_table(struct net_device *dev, u32 new_len)
return -ENOMEM;
}
- for (i = 0;
- old_priomap && (i < old_priomap->priomap_len);
- i++)
- new_priomap->priomap[i] = old_priomap->priomap[i];
+ if (old_priomap)
+ memcpy(new_priomap->priomap, old_priomap->priomap,
+ old_priomap->priomap_len *
+ sizeof(old_priomap->priomap[0]));
new_priomap->priomap_len = new_len;
^ permalink raw reply related
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