I want to use hrtimer, but the module can't work. the source codes is:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/hrtimer.h>
#define US_TO_NS(usec) ((usec) * 1000)
#define MS_TO_US(msec) ((msec) * 1000)
#define MS_TO_NS(msec) ((msec) * 1000 * 1000)
DEFINE_PER_CPU(struct hrtimer, send_hr_timer);
enum hrtimer_restart hrtimer_send_skb(struct hrtimer *timer)
{
ktime_t ktime;
int cpu;
unsigned long delay_in_ms = 10000L; //unsigned long delay_in_us = 5000L;
ktime = ktime_set(0, MS_TO_NS(delay_in_ms));
//ktime = ktime_set(0, US_TO_NS(delay_in_us));
cpu = get_cpu(); printk(KERN_INFO "hrtimer is on:%d", cpu);
hrtimer_forward(&per_cpu(send_hr_timer, cpu), ktime_get(), ktime);
put_cpu();
return HRTIMER_RESTART;
//return HRTIMER_NORESTART;
}
void init_hr_timer(void)
{
ktime_t ktime;
int cpu;
unsigned long delay_in_ms = 100L;
ktime = ktime_set(0, MS_TO_NS(delay_in_ms));
for_each_online_cpu(cpu) {
hrtimer_init(&per_cpu(send_hr_timer, cpu), CLOCK_MONOTONIC, HRTIMER_MODE_REL);
per_cpu(send_hr_timer, cpu).function = &hrtimer_send_skb;
hrtimer_start(&per_cpu(send_hr_timer, cpu), ktime, HRTIMER_MODE_REL);
}
}
void del_hr_timer(void)
{
int cpu;
for_each_online_cpu(cpu) {
/* del hrtimer. */
hrtimer_cancel(&per_cpu(send_hr_timer, cpu));
}
}
static int minit(void)
{
int rc = 0;
printk("Start %s.\n", THIS_MODULE->name);
init_hr_timer();
return rc;
}
static void mexit(void)
{
printk("Exit %s.\n", THIS_MODULE->name);
del_hr_timer();
}
When I install the module, something is error, the messages is:
BUG: soft lockup - CPU#22 stuck for 67s! [migration/22:92]
Modules linked in: ws_hrtimer(U) wscubic(U) wsfasttcp(U) 8021q garp stp llc autofs4 cpufreq_ondemand acpi_cpufreq freq_table mperf be2iscsi iscsi_boot_sysfs ib_iser rdma_cm ib_cm iw_cm ib_sa ib_mad ib_core ib_addr iscsi_tcp bnx2i cnic uio ipv6 cxgb3i libcxgbi cxgb3 mdio libiscsi_tcp libiscsi scsi_transport_iscsi ext3 jbd dm_mirror dm_multipath video output sbs sbshc power_meter wsrelay(U) wsgetsnd(U) parport sg acpi_pad ses enclosure igb dca sb_edac edac_core i2c_i801 i2c_core pata_acpi ata_generic iTCO_wdt iTCO_vendor_support dm_raid45 dm_memcache xor dm_region_hash dm_log dm_mod usb_storage ata_piix isci libsas shpchp mpt2sas scsi_transport_sas raid_class ext4 mbcache jbd2 [last unloaded: microcode]
CPU 22
Modules linked in: ws_hrtimer(U) wscubic(U) wsfasttcp(U) 8021q garp stp llc autofs4 cpufreq_ondemand acpi_cpufreq freq_table mperf be2iscsi iscsi_boot_sysfs ib_iser rdma_cm ib_cm iw_cm ib_sa ib_mad ib_core ib_addr iscsi_tcp bnx2i cnic uio ipv6 cxgb3i libcxgbi cxgb3 mdio libiscsi_tcp libiscsi scsi_transport_iscsi ext3 jbd dm_mirror dm_multipath video output sbs sbshc power_meter wsrelay(U) wsgetsnd(U) parport sg acpi_pad ses enclosure igb dca sb_edac edac_core i2c_i801 i2c_core pata_acpi ata_generic iTCO_wdt iTCO_vendor_support dm_raid45 dm_memcache xor dm_region_hash dm_log dm_mod usb_storage ata_piix isci libsas shpchp mpt2sas scsi_transport_sas raid_class ext4 mbcache jbd2 [last unloaded: microcode]
Pid: 92, comm: migration/22 Not tainted 2.6.32-358.6.1.ws5.b.5.2.8 #1 Inspur SA5212H2/SA5212H2
RIP: 0010:[<ffffffff810c6709>] [<ffffffff810c6709>] stop_machine_cpu_stop+0x59/0x100
RSP: 0018:ffff880874733de0 EFLAGS: 00000293
RAX: 0000000000000001 RBX: ffff880874733e10 RCX: 0000000000000028
RDX: ffffffff81c059e0 RSI: 0000000000000018 RDI: ffffffff81c059e0
RBP: ffffffff8100ba8e R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000
R13: 0000000000000000 R14: ffff881074f0e040 R15: 0000000000000082
FS: 0000000000000000(0000) GS:ffff88089c540000(0000) knlGS:0000000000000000
CS: 0010 DS: 0018 ES: 0018 CR0: 000000008005003b
CR2: 000000373c89ac00 CR3: 0000000001a85000 CR4: 00000000000407e0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Process migration/22 (pid: 92, threadinfo ffff880874732000, task ffff880874731540)
Stack:
0000001674733e00 ffff88089c550840 ffff880874731540 ffffffff810c66b0
<d> ffff8806fa783e68 ffff8806fa783dd8 ffff880874733ee0 ffffffff810c68d5
<d> 0000000000000000 0000002165ed0d57 0000000000000082 ffff880874415ca0
Call Trace:
[<ffffffff810c66b0>] ? stop_machine_cpu_stop+0x0/0x100
[<ffffffff810c68d5>] ? cpu_stopper_thread+0xa5/0x170
[<ffffffff8105a992>] ? default_wake_function+0x12/0x20
[<ffffffff8104e1eb>] ? __wake_up_common+0x5b/0x90
[<ffffffff810c6830>] ? cpu_stopper_thread+0x0/0x170
[<ffffffff810c6830>] ? cpu_stopper_thread+0x0/0x170
[<ffffffff81090ce6>] ? kthread+0x96/0xa0
[<ffffffff8100bfca>] ? child_rip+0xa/0x20
[<ffffffff81090c50>] ? kthread+0x0/0xa0
[<ffffffff8100bfc0>] ? child_rip+0x0/0x20
Code: 18 48 85 c0 0f 84 9b 00 00 00 0f a3 18 19 c0 85 c0 41 0f 95 c6 31 c0 45 31 ff eb 0d 66 0f 1f 44 00 00 83 fb 04 74 3b 89 d8 f3 90 <41> 8b 5c 24 20 39 c3 74 ee 83 fb 02 74 49 83 fb 03 74 54 f0 41
Call Trace:
[<ffffffff810c66b0>] ? stop_machine_cpu_stop+0x0/0x100
[<ffffffff810c68d5>] ? cpu_stopper_thread+0xa5/0x170
[<ffffffff8105a992>] ? default_wake_function+0x12/0x20
[<ffffffff8104e1eb>] ? __wake_up_common+0x5b/0x90
[<ffffffff810c6830>] ? cpu_stopper_thread+0x0/0x170
[<ffffffff810c6830>] ? cpu_stopper_thread+0x0/0x170
[<ffffffff81090ce6>] ? kthread+0x96/0xa0
[<ffffffff8100bfca>] ? child_rip+0xa/0x20
[<ffffffff81090c50>] ? kthread+0x0/0xa0
[<ffffffff8100bfc0>] ? child_rip+0x0/0x20
please help me, thank you.
Related
I am receiving a page allocation failure when calling dma_alloc_coherent() after a number of runs. I have plenty of CMA setup on boot (3GB). I am also making sure that dma_free_coherent() is called on every DMA before the next run. I am at a loss figuring out what could be causing this failure. Any insight or ideas is welcome. Thanks!
[84060.080230] Main: page allocation failure: order:10, mode:0xcc4(GFP_KERNEL|GFP_DMA32), nodemask=(null),cpuset=/,mems_allowed=0
[84060.080248] CPU: 0 PID: 7462 Comm: Main Tainted: G OE 5.15.85evl-g0b08924b969c #3
[84060.080252] Hardware name: Supermicro Super Server/X10SDV-6C-TLN4F, BIOS 1.3 02/13/2018
[84060.080253] IRQ stage: Linux
[84060.080255] Call Trace:
[84060.080257] <TASK>
[84060.080260] dump_stack_lvl+0x81/0xbe
[84060.080268] dump_stack+0x10/0x16
[84060.080271] warn_alloc.cold.144+0x7b/0xdd
[84060.080279] ? __alloc_pages_direct_compact+0x169/0x180
[84060.080285] __alloc_pages_slowpath.constprop.133+0xca9/0xcd0
[84060.080290] ? inband_irq_restore+0x2b/0x40
[84060.080295] ? inband_irq_restore+0x2b/0x40
[84060.080298] __alloc_pages+0x2af/0x2d0
[84060.080303] __dma_direct_alloc_pages.constprop.24+0x181/0x220
[84060.080310] dma_direct_alloc+0x45/0x170
[84060.080314] dma_alloc_attrs+0x39/0x60
[84060.080318] alloc_dma_buf+0x9d/0xe0 [dma_buf_mgr]
[84060.080324] dma_buf_mgr_ioctl+0xa9/0x280 [dma_buf_mgr]
[84060.080329] __x64_sys_ioctl+0x91/0xd0
[84060.080334] do_syscall_64+0x4c/0xa0
[84060.080338] entry_SYSCALL_64_after_hwframe+0x61/0xcb
[84060.080344] RIP: 0033:0x7f4ac00d2307
[84060.080348] Code: 44 00 00 48 8b 05 69 1b 2d 00 64 c7 00 26 00 00 00 48 c7 c0 ff ff ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 b8 10 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 39 1b 2d 00 f7 d8 64 89 01 48
[84060.080351] RSP: 002b:00007f4ad1e67568 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
[84060.080355] RAX: ffffffffffffffda RBX: 00000000ac0a0e00 RCX: 00007f4ac00d2307
[84060.080357] RDX: 00007f4ad1e67580 RSI: 00000000c0102500 RDI: 0000000000000070
[84060.080359] RBP: 00000000002dc6c0 R08: 00007f4ad1e78700 R09: 00007f4ad1e67ac8
[84060.080361] R10: 0000000000000000 R11: 0000000000000246 R12: 00000000002dc6c0
[84060.080363] R13: 00007f4ad1e67ae8 R14: 00007f4ad1e679e0 R15: 00000000ac0b5980
[84060.080366] </TASK>
[84060.080367] Mem-Info:
[84060.080370] active_anon:269 inactive_anon:1461195 isolated_anon:0
active_file:526596 inactive_file:641587 isolated_file:0
unevictable:1089001 dirty:7 writeback:0
slab_reclaimable:74489 slab_unreclaimable:24737
mapped:71474 shmem:4450 pagetables:9652 bounce:0
kernel_misc_reclaimable:0
free:88878 free_pcp:1012 free_cma:20953
[84060.080377] Node 0 active_anon:1076kB inactive_anon:5844780kB active_file:2106384kB inactive_file:2566348kB unevictable:4356004kB isolated(anon):0kB isolated(file):0kB mapped:285896kB dirty:28kB writeback:0kB shmem:17800kB shmem_thp: 0kB shmem_pmdmapped: 0kB anon_thp: 2019328kB writeback_tmp:0kB kernel_stack:7936kB pagetables:38608kB all_unreclaimable? no
[84060.080384] Node 0 DMA free:11264kB min:64kB low:80kB high:96kB reserved_highatomic:0KB active_anon:0kB inactive_anon:0kB active_file:0kB inactive_file:0kB unevictable:0kB writepending:0kB present:15972kB managed:15360kB mlocked:0kB bounce:0kB free_pcp:0kB local_pcp:0kB free_cma:0kB
[84060.080390] lowmem_reserve[]: 0 1800 15786 15786 15786
[84060.080397] Node 0 DMA32 free:90408kB min:7696kB low:9620kB high:11544kB reserved_highatomic:6144KB active_anon:64kB inactive_anon:418192kB active_file:311208kB inactive_file:8kB unevictable:968252kB writepending:8kB present:1975960kB managed:1910424kB mlocked:968252kB bounce:0kB free_pcp:520kB local_pcp:520kB free_cma:0kB
[84060.080404] lowmem_reserve[]: 0 0 13986 13986 13986
[84060.080410] Node 0 Normal free:253840kB min:59820kB low:74772kB high:89724kB reserved_highatomic:2048KB active_anon:1012kB inactive_anon:5426476kB active_file:1795176kB inactive_file:2566340kB unevictable:3387752kB writepending:20kB present:14680064kB managed:14326668kB mlocked:3387752kB bounce:0kB free_pcp:4156kB local_pcp:0kB free_cma:83812kB
[84060.080417] lowmem_reserve[]: 0 0 0 0 0
[84060.080424] Node 0 DMA: 0*4kB 0*8kB 0*16kB 0*32kB 0*64kB 0*128kB 0*256kB 0*512kB 1*1024kB (U) 1*2048kB (M) 2*4096kB (M) = 11264kB
[84060.080443] Node 0 DMA32: 36*4kB (UM) 133*8kB (UME) 309*16kB (UME) 305*32kB (UME) 197*64kB (UME) 138*128kB (UME) 67*256kB (UME) 16*512kB (UME) 1*1024kB (E) 9*2048kB (ME) 0*4096kB = 90984kB
[84060.080468] Node 0 Normal: 6742*4kB (UEC) 5324*8kB (UEHC) 3012*16kB (UMEHC) 1297*32kB (UMEHC) 415*64kB (UMEHC) 192*128kB (MEC) 1*256kB (C) 0*512kB 1*1024kB (C) 11*2048kB (C) 5*4096kB (C) = 254680kB
[84060.080495] Node 0 hugepages_total=0 hugepages_free=0 hugepages_surp=0 hugepages_size=1048576kB
[84060.080497] Node 0 hugepages_total=0 hugepages_free=0 hugepages_surp=0 hugepages_size=2048kB
[84060.080500] 1201421 total pagecache pages
[84060.080501] 0 pages in swap cache
[84060.080502] Swap cache stats: add 0, delete 0, find 0/0
[84060.080504] Free swap = 0kB
[84060.080505] Total swap = 0kB
[84060.080507] 4167999 pages RAM
[84060.080508] 0 pages HighMem/MovableOnly
[84060.080509] 104886 pages reserved
[84060.080510] 786432 pages cma reserved
[84060.080511] 0 pages hwpoisoned
[84060.080513] dma_buf_mgr ALRM: alloc_dma_buf: 14: Failed to allocated DMA buffer
I increased the amount of CMA in order to try and resolve this problem and it did not solve it. It did however increase the number of runs until I see this problem.
I have a Customized board which interfaces over USB.. I am writing USB Linux driver.
Everything is working fine when I test it on my Virtual Machine.. But when I switch to the real hardware and use Yocto on hardware and run the following code.. It fails with -EAGAIN..
retval = usb_control_msg(serial->dev,
usb_rcvctrlpipe(serial->dev, 0),
CP210X_GET_MDMSTS,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
0,
i,
(void *)&modem_status,
1,
USB_CTRL_SET_TIMEOUT);
retval returns with -11. I am not sure why this is not happening on the Virtual Machine, as the only difference is that the PIC Board gets connected to X86 Customized board and runs linux..
dmesg output:
transfer buffer not dma capable
------------[ cut here ]------------
WARNING: CPU: 1 PID: 754 at /usr/src/kernel/drivers/usb/core/hcd.c:1595 usb_hcd_map_urb_for_dma+0x3e6/0x5b0
Modules linked in: cp2108(O)
CPU: 1 PID: 754 Comm: test_quad Tainted: G O 4.14.68-intel-pk-standard #1
task: ffff9a33b7d4a4c0 task.stack: ffff9ce5c0130000
RIP: 0010:usb_hcd_map_urb_for_dma+0x3e6/0x5b0
RSP: 0018:ffff9ce5c0133b08 EFLAGS: 00010296
RAX: 000000000000001f RBX: ffff9a33b7d89780 RCX: 0000000000000000
RDX: ffff9a33bfc9d680 RSI: ffff9a33bfc95598 RDI: ffff9a33bfc95598
RBP: ffff9ce5c0133b28 R08: 0000000000000001 R09: 0000000000000328
R10: ffff9a33ba840068 R11: 0000000000000000 R12: ffff9a33ba2ea000
R13: 00000000fffffff5 R14: 0000000001400000 R15: 0000000000000200
FS: 00007fac9eeed4c0(0000) GS:ffff9a33bfc80000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000003c334e3cb0 CR3: 0000000179498000 CR4: 00000000003406e0
Call Trace:
usb_hcd_submit_urb+0x420/0xa00
? tty_port_open+0xa7/0xd0
? tty_ldisc_unlock+0x1a/0x20
? tty_open_proc_set_tty+0x7f/0xb0
? tty_unlock+0x29/0x40
? tty_open+0x38e/0x450
usb_submit_urb+0x364/0x550
usb_start_wait_urb+0x5f/0xe0
usb_control_msg+0xc5/0x110
cp210x_ioctl+0x4d2/0xe20 [cp2108]
? filemap_map_pages+0x129/0x290
? do_filp_open+0xa0/0xf0
serial_ioctl+0x46/0x50
tty_ioctl+0xe7/0x870
do_vfs_ioctl+0x99/0x5e0
? putname+0x4c/0x60
SyS_ioctl+0x79/0x90
Can you guys please provide a hint for me to try.. Appreciate your time and efforts.
I got the solution Kernel >= 4.9 no longer accepts any statically allocated buffer.
Modified the code to use dynamic memory and it worked.
modem_status = kmalloc(sizeof(unsigned long), GFP_KERNEL);
if (!modem_status)
return -ENOMEM;
for (i = 0; i < MAX_CP210x_INTERFACE_NUM; i++) {
retval = usb_control_msg(serial->dev,
usb_rcvctrlpipe(serial->dev, 0),
CP210X_GET_MDMSTS,
USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_INTERFACE,
0,
i,
(void *)modem_status,
1,
USB_CTRL_SET_TIMEOUT);
I'm modifying the UDP protocol such that when connect() is called on a UDP socket, in addition to finding the route, a "Hello" packet is also sent to the destination.
From the UDP proto structure, I figured out that the function ip4_datagram_connect does the job of finding the route to the destination. Now at the end of this function, I need to send the Hello packet.
I don't think I can use udp_sendmsg() as it's used for copying and sending data from the userspace.
I think udp_send_skb() should be used to sent the hello. My problem is I don't know how to create an appropriate skbuff to store the Hello message (it should be a proper udp datagram) to be passed on to udp_send_skb(). I've tried this
int quic_connect(struct sock *sk, struct flowi4 *fl4, struct rtable *rt){
struct sk_buff *skb;
char *hello;
int err = 0, exthdrlen, hh_len, datalen, trailerlen;
char *data;
hh_len = LL_RESERVED_SPACE(rt->dst.dev);
exthdrlen = rt->dst.header_len;
trailerlen = rt->dst.trailer_len;
datalen = 200;
//Create a buffer to be send without fragmentation
skb = sock_alloc_send_skb(sk,
exthdrlen + datalen + hh_len + trailerlen + 15,
MSG_DONTWAIT, &err);
if (skb == NULL)
goto out;
skb->ip_summed = CHECKSUM_PARTIAL; // Use hardware checksum
skb->csum = 0;
skb_reserve(skb, hh_len);
skb_shinfo(skb)->tx_flags = 1; //Time stamp the packet
/*
* Find where to start putting bytes.
*/
data = skb_put(skb, datalen + exthdrlen);
skb_set_network_header(skb, exthdrlen);
skb->transport_header = (skb->network_header +
sizeof(struct iphdr));
err = udp_send_skb(skb, fl4);
However, this gives me errors in the kernel log
BUG: unable to handle kernel NULL pointer dereference at 0000000000000018
IP: [<ffffffff81686555>] __ip_local_out+0x45/0x80
PGD 4f4dd067 PUD 4f4df067 PMD 0
Oops: 0000 [#1] SMP
Modules linked in:
CPU: 0 PID: 3019 Comm: client Not tainted 3.13.11-ckt39-test006 #28
Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
task: ffff8800598df6b0 ti: ffff880047022000 task.ti: ffff880047022000
RIP: 0010:[<ffffffff81686555>] [<ffffffff81686555>] __ip_local_out+0x45/0x80
RSP: 0018:ffff880047023d78 EFLAGS: 00010287
RAX: 0000000000000001 RBX: ffff880047008a00 RCX: 0000000020000000
RDX: 0000000000000000 RSI: ffff880047008a00 RDI: ffff8800666fde40
RBP: ffff880047023d88 R08: 0000000000003200 R09: 0000000000000001
R10: 0000000000000000 R11: 00000000000001f9 R12: ffff880047008a00
R13: ffff8800666fde80 R14: ffff880059aec380 R15: ffff880059aec690
FS: 00007f5508b04740(0000) GS:ffff88007fc00000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b
CR2: 0000000000000018 CR3: 000000004f561000 CR4: 00000000000406f0
DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
Stack:
ffff880047023d80 ffff880047008a00 ffff880047023da0 ffffffff8168659d
ffffffff81c8f8c0 ffff880047023db8 ffffffff81687810 0000000000000000
ffff880047023df8 ffffffff816ac6be 0000000000000020 ffff880047008a00
Call Trace:
[<ffffffff8168659d>] ip_local_out+0xd/0x30
[<ffffffff81687810>] ip_send_skb+0x10/0x40
[<ffffffff816ac6be>] udp_send_skb+0x14e/0x3d0
[<ffffffff816b0e9e>] quic_connect+0x6e/0x80
[<ffffffff816aa3ff>] __ip4_datagram_connect+0x2bf/0x2d0
[<ffffffff816aa437>] ip4_datagram_connect+0x27/0x40
[<ffffffff816b8748>] inet_dgram_connect+0x38/0x80
[<ffffffff8161fd97>] SYSC_connect+0xc7/0x100
[<ffffffff817ed471>] ? __schedule+0x341/0x8c0
[<ffffffff816206e9>] SyS_connect+0x9/0x10
[<ffffffff817f8d42>] system_call_fastpath+0x16/0x1b
Code: c8 00 00 00 66 c1 c0 08 66 89 47 02 e8 d5 e0 ff ff 48 8b 53 58 b8 01 00 00 00 48 83 e2 fe 48 81 3d 9d 0e 64 00 f0 73 cc 81 74 26 <4c> 8b 42 18 49 c7 c1 f0 45 68 81 c7 04 24 00 00 00 80 31 c9 48
RIP [<ffffffff81686555>] __ip_local_out+0x45/0x80
RSP <ffff880047023d78>
CR2: 0000000000000018
---[ end trace 474c5db1b9b19a03 ]---
So my question is, what else do I need to fill in my skbuff before it can be handled properly by udp_send_skb. Or am I missing something else here?
There is a bug in your code.
if (skb_tailroom(hbuff) > 30) {
printk(" Enough room for QUIC connect message\n");
hello = kmalloc(30, GFP_ATOMIC); //You allocate slub memory
hello = "Hello from QUIC connect"; //You let 'hello' point to a string,
//which is stored somewhere else.
//At this point, your slub memory
//allocated is lost.
memcpy(__skb_put(hbuff, 30), hello, 30);
kfree(hello); //You try to free the memory pointed by
//hello as slub memory, I think this is
// why you get mm/slub.c bug message.
} else
You can change your code like this:
if (skb_tailroom(hbuff) > 30) {
printk(" Enough room for QUIC connect message\n");
memcpy(__skb_put(hbuff, 30), "Hello from QUIC connect", 30);
} else
I just used the functions ip_make_skb followed by ip_send_skb. Since ip_make_skb is used to copy data from user space and I didn't need to do that, I just used a dummy pointer and provided the length to be copied as Zero (+sizeof udphdr, as required by this function). It's a dirty way to do it, but it works for now.
My code:
int quic_connect(struct sock *sk, struct flowi4 *fl4, struct rtable *rt, int oif){
struct sk_buff *skb;
struct ipcm_cookie ipc;
void *hello = "Hello";
int err = 0;
ipc.opt = NULL;
ipc.tx_flags = 1;
ipc.ttl = 0;
ipc.tos = -1;
ipc.oif = oif;
ipc.addr = fl4->daddr;
skb = ip_make_skb(sk, fl4, ip_generic_getfrag, hello, sizeof(struct udphdr),
sizeof(struct udphdr), &ipc, &rt,
0);
err = PTR_ERR(skb);
if (!IS_ERR_OR_NULL(skb)){
err = udp_send_skb(skb, fl4);
}
return err;
}
Tried building the RoCC accelerator default accumulator example for zed board, but getting an error of "illegal instruction"
I tried the below config in the configs.scala file:-
class WithAccumRocc extends Config(
(pname,site,here) => pname match {
case RoccNMemChannels => 1
case RoccMaxTaggedMemXacts => 0
case BuildRoCC => {
Some((p: Parameters) =>
Module(new AccumulatorExample()(p.alterPartial({ case CoreName => "AccumRocc" }))))
}
}
)
class WithRoCCConfig extends Config(new WithAccumRocc ++ new DefaultFPGAConfig)
The bitstream was generated successfully but when i ran the dummy_rocc_test binary generated from the example given in riscv-isa-sim, i got the following error on the zed board.
root#zynq:~# ./fesvr-zynq pk /sdcard/Custom\ elfs/dummy_rocc
z 0000000000000000 ra 0000000000010044 sp 000000000feffb10 gp 0000000000017880
tp 0000000000000000 t0 0000000000017178 t1 0000000000017178 t2 0000000000000000
s0 000000000feffb40 s1 0000000000000000 a0 0000000000000001 a1 000000000feffb48
a2 0000000000000000 a3 0000000000000000 a4 0000000000000000 a5 000000000000007b
a6 0000000000000000 a7 0000000000000001 s2 0000000000000000 s3 0000000000000000
s4 0000000000000000 s5 0000000000000000 s6 0000000000000000 s7 0000000000000000
s8 0000000000000000 s9 0000000000000000 sA 0000000000000000 sB 0000000000000000
t3 0000000000000000 t4 0000000000000000 t5 0000000000000000 t6 0000000000000000
pc 0000000000010168 va 0000000000010168 insn 0027e00b sr 8000000000003008
An illegal instruction was executed!
Any help here would be greatly appreciated.
P.S. :- The dummy_rocc_test example is working fine with spike and has been compiled with riscv64-unknown-elf-gcc
Hello guys this issue has been resolved, once the change was made the rocket needs to be built with the new pga configuration and the vivid project must also be updated accordingly in order to generate the new bitstream.
I was trying to write a pci driver which can display the MAC address of my Ethernet card.
Running a Ubuntu on VM and my Ethernet card is Intel one as follows
00:08.0 Ethernet controller: Intel Corporation 82540EM Gigabit Ethernet Controller (rev 02)
I was able to get the data sheet of the same from Intel website and as per data sheet it says IO address are mapped to Bar 2 (Refer to pg 87) and MAC can be read using RAL/RAH register which are at offset RAL (05400h + 8*n; R/W) and RAH (05404h + 8n; R/W)
2 18h IO Register Base Address (bits 31:2) 0b mem
Based on this information, i wrote a small PCI driver but i always get the MAC as fff and when i debugged further, i see io_base address is always zero.
Below is the code
1 /*
2 Program to find a device on the PCI sub-system
3 */
4 #define VENDOR_ID 0x8086
5 #define DEVICE_ID 0x100e
6
7 #include <linux/kernel.h>
8 #include <linux/module.h>
9 #include <linux/stddef.h>
10 #include <linux/pci.h>
11 #include <linux/init.h>
12 #include <linux/cdev.h>
13 #include <linux/device.h>
14 #include <asm/io.h>
15
16 #define LOG(string...) printk(KERN_INFO string)
17
18 #define CDEV_MAJOR 227
19 #define CDEV_MINOR 0
20
21
22 MODULE_LICENSE("GPL");
23
24 struct pci_dev *pci_dev;
25 unsigned long mmio_addr;
26 unsigned long reg_len;
27 unsigned long *base_addr;
28
29 int device_probe(struct pci_dev *dev, const struct pci_device_id *id);
30 void device_remove(struct pci_dev *dev);
31
32 struct pci_device_id pci_device_id_DevicePCI[] =
33 {
34 {VENDOR_ID, DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
35 };
36
37 struct pci_driver pci_driver_DevicePCI =
38 {
39 name: "MyPCIDevice",
40 id_table: pci_device_id_DevicePCI,
41 probe: device_probe,
42 remove: device_remove
43 };
44
45
46 int init_module(void)
47 {
48 //struct pci_dev *pdev = NULL;
49 int ret = 0;
50
51 pci_register_driver(&pci_driver_DevicePCI);
52
53 return ret;
54 }
55
56 void cleanup_module(void)
57 {
58 pci_unregister_driver(&pci_driver_DevicePCI);
59
60 }
61
62 #define REGISTER_OFFSET 0x05400
64 int device_probe(struct pci_dev *dev, const struct pci_device_id *id)
65 {
66 int ret;
67 int bar = 2; // Bar to be reserved
68 unsigned long io_base = 0;
69 unsigned long mem_len = 0;
70 unsigned int register_data = 0;
71
72 LOG("Device probed");
73
74 /* Reserve the access to PCI device */
75 ret = pci_request_region(dev, bar, "my_pci");
76 if (ret) {
77 printk(KERN_ERR "request region failed :%d\n", ret);
78 return ret;
79 }
80
81 ret = pci_enable_device(dev);
82 if (ret < 0 ) LOG("Failed while enabling ... ");
83
84 io_base = pci_resource_start(dev, bar);
85 mem_len = pci_resource_len(dev, bar);
86
87 request_region(io_base, mem_len, "my_pci");
88 register_data = inw(io_base + REGISTER_OFFSET);
89 printk(KERN_INFO "IO base = %lx", io_base);
90 printk(KERN_INFO "MAC = %x", register_data);
91
92 return ret;
93 }
94
95 void device_remove(struct pci_dev *dev)
96 {
97 pci_release_regions(dev);
98 pci_disable_device(dev);
99 }
100
lspci -x output of my card
00:08.0 Ethernet controller: Intel Corporation 82540EM Gigabit Ethernet Controller (rev 02)
00: 86 80 0e 10 07 00 30 02 02 00 00 02 00 40 00 00
10: 00 00 82 f0 00 00 00 00 41 d2 00 00 00 00 00 00
20: 00 00 00 00 00 00 00 00 00 00 00 00 86 80 1e 00
30: 00 00 00 00 dc 00 00 00 00 00 00 00 09 01 ff 00
Can any one let me know what am i doing wrong?
I've modified your code and commented on changes. I have removed all of your existing comments to avoid confusion, and have only modified your probe function.
/* We need a place to store a logical address for unmapping later */
static void* logical_address;
int device_probe(struct pci_dev *dev, const struct pci_device_id *id)
{
int ret;
int bar_mask; /* BAR mask (this variable) and the integer BAR */
int requested_bar = 2; /* (this variable) are not the same thing, so give them */
/* separate variables */
resource_size_t io_base = 0; /* use kernel macros instead of built-in datatypes */
resource_size_t mem_len = 0;
unsigned int register_data = 0;
LOG("Device probed");
/* add this call to get the correct BAR mask */
bar_mask = pci_select_bars(dev, 0);
/* switched order - enable device before requesting memory */
ret = pci_enable_device(dev);
if (ret < 0 ) LOG("Failed while enabling ... ");
/* for this call, we want to pass the BAR mask, NOT the integer bar we want */
ret = pci_request_region(dev, bar_mask, "my_pci");
if (ret) {
printk(KERN_ERR "request region failed :%d\n", ret);
return ret;
}
/* it is in THESE calls that we request a specific BAR */
io_base = pci_resource_start(dev, requested_bar);
mem_len = pci_resource_len(dev, requested_bar);
/* you don't need to request anything again, so get rid of this line: */
/* request_region(io_base, mem_len, "my_pci"); */
/* you're missing an important step: we need to translate the IO address
* to a kernel logical address that we can actually use. Add a call to
* ioremap()
*/
logical_address = ioremap(io_base, mem_len);
/* we need to use the logical address returned by ioremap(), not the physical
* address returned by resource_start
*/
register_data = inw(logical_address + REGISTER_OFFSET);
printk(KERN_INFO "IO base = %lx", io_base);
printk(KERN_INFO "MAC = %x", register_data);
return ret;
}
You will need to add a corresponding call to iounmap() in your device_remove() routine. Take a look at the Intel E100E driver source code for some good examples.