From: Daniel Borkmann <dborkman@redhat.com>
To: Dave Jones <davej@redhat.com>
Cc: netdev@vger.kernel.org,
Fedora Kernel Team <kernel-team@fedoraproject.org>,
Vlastimil Babka <vbabka@suse.cz>,
Michel Lespinasse <walken@google.com>
Subject: Re: packet mmap related oops (with reproducer)
Date: Wed, 22 Jan 2014 23:45:49 +0100 [thread overview]
Message-ID: <52E04A1D.8080803@redhat.com> (raw)
In-Reply-To: <20140122223920.GA18162@redhat.com>
Hi Dave,
On 01/22/2014 11:39 PM, Dave Jones wrote:
> We had a Fedora user report this bug, with a reproducer (below).
>
> On Fri, Jan 17, 2014 at 06:52:06AM +0000, bugzilla@redhat.com wrote:
> > https://bugzilla.redhat.com/show_bug.cgi?id=1054537
> >
> >
> >
> > --- Comment #2 from Karl Auerbach <karl@iwl.com> ---
> > --> https://bugzilla.redhat.com/attachment.cgi?id=851413
> > Simple program to cause this kernel issue
> >
> > This is a C program that must be run with root privilege. It runs fine on
> > older kernels but causes a kernel problem on the most recent one.
> >
> > The code creates a raw socket with transmit and receive ring buffers.
> >
> > The rings are then made visible via mmap().
> >
> > When munmap() is called things go awry.
> >
> > The code in this example was quickly lifted from a larger body of code that has
> > been running for several years.
It looks to be THP related, you can also use the Linux kernel
selftest suite for networking to trigger that, I've reported
it here:
https://lkml.org/lkml/2014/1/10/427
Vlastimil seems to have proposed some possibilities, but it
seems discussion stalled for now.
Cheers,
Daniel
> #include <assert.h>
> #include <errno.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <stdarg.h>
> #include <unistd.h>
>
> #include <arpa/inet.h>
> #include <sys/ioctl.h>
> #include <sys/mman.h>
> #include <sys/socket.h>
> #include <sys/un.h>
> #include <sys/user.h>
>
> #include <features.h> /* for the glibc version number */
> #include <net/ethernet.h>
> #include <linux/if_packet.h>
> #include <linux/if_ether.h>
>
> #include <net/if.h>
> #include <netinet/in.h>
> #include <sys/ioctl.h>
> #include <sys/types.h>
> #include <linux/if_tun.h>
>
> #define NIL 0
>
> typedef int SOCKET;
>
> int main(int argc, char *argv)
> {
> size_t RxMmap_Size;
> size_t TxMmap_Size;
> unsigned int Ether_Sz;
> unsigned int Block_Sz_Order;
> unsigned int Block_Sz;
> unsigned int Block_Cnt;
> unsigned int Frame_Sz;
> unsigned int Frame_Cnt;
> unsigned int Frames_Per_Block;
>
> void * Mmap_Addr;
> size_t Mmap_Size;
> size_t TXDataOffset;
>
> SOCKET Socket;
>
> struct tpacket_req ring_req;
>
> Ether_Sz = 1518;
> Block_Sz = Ether_Sz;
> Block_Sz_Order = 2; // 16384 byte blocks
> Block_Cnt = 1000;
>
> Socket = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
> if (Socket == -1)
> {
> perror("socket failed");
> return 1;
> }
>
> Frame_Sz = TPACKET_ALIGN(TPACKET_ALIGN(TPACKET2_HDRLEN) + Ether_Sz);
> TXDataOffset = TPACKET2_HDRLEN - sizeof(struct sockaddr_ll);
>
> Block_Sz = getpagesize() << Block_Sz_Order;
>
> Frames_Per_Block = Block_Sz / Frame_Sz;
> Frame_Cnt = Frames_Per_Block * Block_Cnt;
>
> RxMmap_Size = Block_Sz * Block_Cnt;
> TxMmap_Size = RxMmap_Size;
>
> Mmap_Size = RxMmap_Size + TxMmap_Size;
>
> // Establish receive ring
> // For convenience we will let it be the same size as the TX ring
> // The mmap size calculations, far above, assume that the
> // rings are the same size.
> ring_req.tp_block_nr = Block_Cnt;
> ring_req.tp_frame_size = Frame_Sz;
> ring_req.tp_block_size = Block_Sz;
> ring_req.tp_frame_nr = Frame_Cnt;
> if (setsockopt(Socket, SOL_PACKET, PACKET_RX_RING,
> (char *)&ring_req, sizeof(ring_req)) < 0)
> {
> perror("Setsockopt RX_RING failed");
> close(Socket);
> return -1;
> }
>
> // Establish transmit ring
> // For convenience we will let it be the same size as the RX ring
> // The mmap size calculations, far above, assume that the
> // rings are the same size.
> ring_req.tp_block_nr = Block_Cnt;
> ring_req.tp_frame_size = Frame_Sz;
> ring_req.tp_block_size = Block_Sz;
> ring_req.tp_frame_nr = Frame_Cnt;
> if (setsockopt(Socket, SOL_PACKET, PACKET_TX_RING,
> (char *)&ring_req, sizeof(ring_req)) < 0)
> {
> perror("Setsockopt TX_RING failed");
> close(Socket);
> return -1;
> }
>
> Mmap_Addr = mmap(NIL, Mmap_Size, PROT_READ | PROT_WRITE,
> MAP_SHARED | MAP_LOCKED, Socket, 0);
>
> if (Mmap_Addr == MAP_FAILED)
> {
> perror("mmap failed");
> return 1;
> }
>
> if (Mmap_Addr != MAP_FAILED)
> {
> (void)munmap(Mmap_Addr, Mmap_Size);
> }
>
> close(Socket);
> return 0;
> }
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
prev parent reply other threads:[~2014-01-22 22:46 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <bug-1054537-176318@bugzilla.redhat.com>
[not found] ` <bug-1054537-176318-JYaNmE5vAr@bugzilla.redhat.com>
2014-01-22 22:39 ` packet mmap related oops (with reproducer) Dave Jones
2014-01-22 22:45 ` Daniel Borkmann [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=52E04A1D.8080803@redhat.com \
--to=dborkman@redhat.com \
--cc=davej@redhat.com \
--cc=kernel-team@fedoraproject.org \
--cc=netdev@vger.kernel.org \
--cc=vbabka@suse.cz \
--cc=walken@google.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.