Re: pci device driver
>I am completely new to this PCI device driver so I just wanted to know that >how kernel build pci_dev structure during pci initialization time. what are >the pci function are being called The sequence of routines that lead to pci device initialization. pci_legacy_init() -> pcibios_scan_root() -> pci_scan_child_bus()-> pci_scan_slot()-> pci_scan_single_device() ->pci_device_add()-> device_add(&dev->dev) -> bus_probe_device() -> device_attach() struct pci_dev *pci_scan_single_device(struct pci_bus *bus, int devfn) { struct pci_dev *dev; dev = pci_get_slot(bus, devfn); if (dev) { pci_dev_put(dev); return dev; } dev = pci_scan_device(bus, devfn); if (!dev) return NULL; pci_device_add(dev, bus); return dev; } /* * Read the config data for a PCI device, sanity-check it * and fill in the dev structure... */ static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn) { struct pci_dev *dev; u32 l; if (!pci_bus_read_dev_vendor_id(bus, devfn, &l, 60*1000)) return NULL; dev = pci_alloc_dev(bus); if (!dev) return NULL; dev->devfn = devfn; dev->vendor = l & 0x; dev->device = (l >> 16) & 0x; pci_set_of_node(dev); if (pci_setup_device(dev)) { pci_bus_put(dev->bus); kfree(dev); return NULL; } return dev; } ___ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
Re: Reading disks sectors
mm/page_io.c static struct bio *get_swap_bio(gfp_t gfp_flags, struct page *page, bio_end_io_t end_io) { bio = bio_alloc(gfp_flags, 1); if (bio) { bio->bi_iter.bi_sector = map_swap_page(page, &bio->bi_bdev); bio->bi_iter.bi_sector <<= PAGE_SHIFT - 9; bio->bi_iter.bi_size = PAGE_SIZE; bio->bi_end_io = end_io; } return bio; } bi_endio() calls bio->bi_end_io. One should assign a routine to bio->bi_end_io. One can wake up the thread waiting for IO in bi_end_io. For example: direct IO has assigned dio_bio_end_io routine to bio->bi_end_io fs/direct-io.c /* * The BIO completion handler simply queues the BIO up for the process-context * handler. * * During I/O bi_private points at the dio. After I/O, bi_private is used to * implement a singly-linked list of completed BIOs, at dio->bio_list. */ static void dio_bio_end_io(struct bio *bio, int error) { struct dio *dio = bio->bi_private; bio->bi_private = dio->bio_list; dio->bio_list = bio; if (--dio->refcount == 1 && dio->waiter) wake_up_process(dio->waiter); } Regards Manoj Nayak ___ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
Re: Acquiring MSI vector physical address from kernel driver
In the following code, msi lower address, higher address and data is written to msi_desc corresponding to a msi vector. http://lxr.free-electrons.com/source/drivers/pci/msi.c#L311 We can get the msi message from irq using irq_get_msi_desc(). http://lxr.free-electrons.com/source/drivers/pci/msi.c#L349 struct msi_desc *entry = irq_get_msi_desc(irq); Regards Manoj Nayak ___ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
Re: Adding new protocol to linux.
Hi Daniel, Some of the Network application use two connections. One connection for control channel to send commands and status update. Other connection is used for real data transfer. For example: FTP. However this needs two socket. TCP talks about out-of-band data transfer using Urgent Pointer flag and Urgent pointer offset in the tcp header. However the data transfer uses the same connection. Regards Manoj Nayak ___ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
Re: Adding new protocol to linux.
> 1) Is it possible to write a new protocol for linux with an out of > tree module without modifing socket.h file? I think this has been already tried in the following code. http://lxr.free-electrons.com/source/include/net/bluetooth/bluetooth.h#L36 http://lxr.free-electrons.com/source/include/linux/socket.h#L239 The challenge is to expose this development specific header file to userspace. The following document talks about that. http://kernelnewbies.org/KernelHeaders Regards Manoj Nayak ___ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
Re: Adding new protocol to linux
> 2) Could netlink socket be used to solve this? .. and Netlink is used to transfer information between kernel and user-space processes. It consists of a standard sockets-based interface for user space processes and an internal kernel API for kernel modules. netlink socket does not call dev_queue_xmit(). But here the requirement is to transfer the packet using Nordic's nRF24L01+. AF_PACKET is used to output a raw packet from userspace to a device layer. Even AF_PACKET does that using proto_ops and net_proto_family. Regards Manoj Nayak ___ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
Re: Contiguous memory allocator
cma_declare_contiguous() allocates memory from memblock. cma_init_reserved_mem() initialize the memory. Then the memory is given to buddy allocator with migration type MIGRATE_MOVABLE. when CMA needs thosepages, it can take it from buddy allocator. We are supposed to use equivalent DMA api dma_declare_contiguous(). dma_declare_contiguous() calls cma_declare_contiguous(). http://lxr.free-electrons.com/source/arch/arm/mach-davinci/devices-da8xx.c#L833 Regards Manoj Nayak ___ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
Re: kmalloc/malloc for dma ?
Please check the following document. https://forums.xilinx.com/xlnx/attachments/xlnx/ELINUX/10693/1/Linux%20DMA%20from%20User%20Space-public.pdf Regards Manoj Nayak ___ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
Re :Querry Regarding Memory Alignment
The CPU always reads at its word size (4 bytes on a 32-bit processor), so when you do an unaligned address access — on a processor that supports it — the processor is going to read multiple words. The CPU will read each word of memory that your requested address straddles. This causes multiple processor read to access the requested data. Hardware deals with word size alignment. Other alignment like page size alignment is a software feature. On X86: Any virtual address provided to cpu is split into page aligned virtual address and an offset.CPU uses page aligned virtual address to check TLB to get page aligned physical address. Now physical address = Page aligned physical address + offset If page size is bigger then less no of TLB entries are required for the processor. Each page needs one TLB entry. Regards Manoj Nayak ___ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
Re: kernel_thread() causes segfault
Process has files_struct and fs_struct in task_struct. Two thread's task_struct can point to same files_struct and fs_struct if we do the changes through a new system call. Please check the following URL. http://lxr.free-electrons.com/source/kernel/fork.c#L993 Regards Manoj Nayak ___ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
Re: How to get object virtual address from a kernel core dump
task_struct contains mm_struct. If we have pid of the process then task_struct can be obtained from pid using following two methods. 1. Please check find_task_by_pid() function in kernel. We can write a similar macro to convert pid to task_struct. 2. We can write a macro that traverses all task starting from init_task and check the required pid. #define for_each_task(p) \ for (p = &init_task ; (p = p->next_task) != &init_task ; ) If process is the current one then current_thread_info()->task provides task_struct for current task. We can write a macro similar to current_thread_info(). pid-> task_struct->mm_struct. Regards Manoj Nayak ___ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
Re:kernel_thread() causes segfault
What is the usecase here ? Do we need to share the entire process address space to a kernel thread ? If address space sharing between userspace thread and kernel thread space is the whole idea then we can mmap process address space and do get_user_pages() to allocate physcial page and pin it. kernel thread can do kmap() and kumap() to use the pages from process address space. http://lxr.free-electrons.com/source/fs/aio.c?v=3.8#L99 Regards Manoj Nayak ___ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
Re: copy offload (copy_file_range) and sendfile()
1. sendfile() and splice uses temporary buffer in terms of pipe. do_splice_direct(in.file, &pos, out.file, &out_pos, count, fl) -> splice_direct_to_actor(struct file *in, struct splice_desc *sd, splice_direct_actor *actor) http://lxr.free-electrons.com/source/fs/splice.c#L602 default_file_splice_read() allocates a page, read data for file1 from disk to the page, then write the page to a pipe. default_file_splice_write() reads from the pipe, writes to a page, then write page to the file2. So this is not a zero-copy in kernel. This can be a zero-copy from userspace point of view as we are not doing copy to userspace. but still a copy is involved a we are doing write to temporary buffer, for example: pipe. 2. if copy_file_range() is defined for a filesystem operation then splice is not used. otherwise copy_file_range() uses splice method of temporary buffer in terms of a pipe. http://lxr.free-electrons.com/source/fs/read_write.c#L1412 ret = file_out->f_op->copy_file_range(file_in, pos_in, file_out, 1413 pos_out, len, flags); 1414 if (ret == -EOPNOTSUPP) 1415 ret = do_splice_direct(file_in, &pos_in, file_out, &pos_out, 1416 len > MAX_RW_COUNT ? MAX_RW_COUNT : len, 0); 1417 copy_file_range() does the following things that is much better method than splice. COPY_FR_COPY means to copy the data normally, accelerating the work at the filesystem level if possible. COPY_FR_REFLINK asks for the destination file to refer to the existing copy of the data without actually copying it. Some filesystems (Btrfs, for example) are able to share references to file blocks in this way. COPY_FR_DEDUP is like COPY_FR_REFLINK, but it only succeeds if the destination range already contains the same data as the source. The end result is files that look the same as before, but which are now sharing the data on-disk. It is thus a way of removing blocks of duplicated data within the filesystem. The COPY_FR_COPY operation will, in the absence of filesystem-level acceleration, copy the data directly through the kernel page cache; it is essentially a splice() operation. Copying through the page cache in this way is clearly more efficient than doing the copy in user space, since it avoids the need to copy the data out of the kernel and back in again. If possible, of course, copying with COPY_FR_REFLINK will be the most efficient approach. copy_file_range() does not do the copy. It does a clone of a range of blocks of a file. 2921 const struct file_operations btrfs_file_operations = { 2922... 2935 .copy_file_range = btrfs_copy_file_range, 2936 .clone_file_range = btrfs_clone_file_range, 2937 .dedupe_file_range = btrfs_dedupe_file_range, 2938 }; 3902 ssize_t btrfs_copy_file_range(struct file *file_in, loff_t pos_in, 3903 struct file *file_out, loff_t pos_out, 3904 size_t len, unsigned int flags) 3905 { 3906 ssize_t ret; 3907 3908 ret = btrfs_clone_files(file_out, file_in, pos_in, len, pos_out); 3909 if (ret == 0) 3910 ret = len; 3911 return ret; 3912 } Regards Manoj Nayak ___ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies