This is the mail archive of the systemtap@sourceware.org mailing list for the systemtap project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RE: Patch [2/3] Userspace probes readpage hooks


>>-----Original Message-----
>>From: systemtap-owner@sourceware.org [mailto:systemtap-owner@sourceware.org] On Behalf Of Prasanna S Panchamukhi
>>Sent: 2006年1月19日 22:40
>>To: systemtap@sources.redhat.com
>>Subject: Re: Patch [2/3] Userspace probes readpage hooks
>>
>>
>>This patch provides the feature to insert the probes on the pages
>>that are not present in the memory during registeration.
>>
>>
>>diff -puN kernel/kprobes.c~kprobes_userspace_probes_hook_readpage kernel/kprobes.c
>>--- linux-2.6.15/kernel/kprobes.c~kprobes_userspace_probes_hook_readpage	2006-01-19 19:37:48.000000000 +0530
>>+++ linux-2.6.15-prasanna/kernel/kprobes.c	2006-01-19 19:37:49.000000000 +0530
>>@@ -815,6 +815,133 @@ static struct uprobe_module __kprobes *g
>> 	return NULL;
>> }
>>
>>+static inline void insert_readpage_uprobe(struct page *page,
>>+	struct address_space *mapping, struct uprobe *uprobe)
>>+{
>>+	struct vm_area_struct *vma = NULL;
>>+
>>+	if (find_page_probe(uprobe->offset >> PAGE_CACHE_SHIFT,
>>+				page->index << PAGE_CACHE_SHIFT)) {
>>+		spin_lock(&mapping->i_mmap_lock);
>>+		vma = find_get_vma(uprobe, page, mapping);
>>+		map_uprobe_page(page, vma, uprobe, insert_kprobe_user);
>>+
>>+		flush_vma(mapping, page, uprobe);
>>+		spin_unlock(&mapping->i_mmap_lock);
>>+	}
>>+}
>>+
>>+/**
>>+ *  This function hooks the readpages() of all modules that have active probes
>>+ *  on them. The original readpages() is called for the given
>>+ *  inode/address_space to actually read the pages into the memory. Then all
>>+ *  probes that are specified on these pages are inserted.
>>+ */
>>+static int __kprobes uprobe_readpages(struct file *file,
>>+				struct address_space *mapping,
>>+				struct list_head *pages, unsigned nr_pages)
>>+{
>>+	int retval = 0;
>>+	struct page *page;
>>+	struct uprobe_module *umodule;
>>+	struct uprobe *uprobe = NULL;
>>+	struct hlist_node *node;
>>+
>>+	mutex_lock(&uprobe_mutex);
>>+
>>+	umodule = get_module_by_inode(file->f_dentry->d_inode);
>>+	if (!umodule) {
[YM] The race condition is still not resolved. 


>>+		printk("uprobe_readpages: we don't have a module \
>>+				associated with this file.. Aborting\n");
>>+		mutex_unlock(&uprobe_mutex);
>>+		return -EINVAL;
>>+	}
>>+
>>+	/* call original readpages() */
>>+	retval = umodule->ori_a_ops->readpages(file, mapping, pages, nr_pages);
>>+	if (retval < 0)
>>+		goto out;
>>+
>>+	/*
>>+	 * TODO: Walk through readpages page list and get
>>+	 * pages with probes instead of find_get_page().
>>+	 */
>>+	mutex_lock(&kprobe_mutex);
>>+	hlist_for_each_entry(uprobe, node, &umodule->ulist_head, ulist) {
>>+		page = find_get_page(mapping,
>>+				uprobe->offset >> PAGE_CACHE_SHIFT);
>>+		if (!page)
>>+			continue;
It's incorrect. Some pages might be in memory and the corresponding uprobe are already inserted on the pages, so the same uprobe might be inserted more once on the same page. You could just go through pages read in by this call.

>>+
>>+		insert_readpage_uprobe(page, mapping, uprobe);
>>+		page_cache_release(page);
>>+	}
>>+	mutex_unlock(&kprobe_mutex);
>>+
>>+out:
>>+	mutex_unlock(&uprobe_mutex);
>>+	return retval;
>>+}
>>+
>>+/**
>>+ *  This function hooks the readpage() of all modules that have active probes
>>+ *  on them. The original readpage() is called for the given inode/address_space
>>+ *  to actually read the pages into the memory. Then all probes that are
>>+ *  specified on this page are inserted.
>>+ */
>>+int __kprobes uprobe_readpage(struct file *file, struct page *page)
>>+{
>>+	int retval = 0;
>>+	struct uprobe_module *umodule;
>>+	struct uprobe *uprobe = NULL;
>>+	struct hlist_node *node;
>>+	struct address_space *mapping = file->f_dentry->d_inode->i_mapping;
>>+
>>+	mutex_lock(&uprobe_mutex);
>>+	umodule = get_module_by_inode(file->f_dentry->d_inode);
>>+	if (!umodule) {
[YM] Same race is not resolved.


>>+		printk("uprobe_readpages: we don't have a module \
>>+				associated with this file.. Aborting\n");
>>+		mutex_unlock(&uprobe_mutex);
>>+		return -EINVAL;
>>+	}
>>+
>>+	/* call original readpage() */
>>+	retval = umodule->ori_a_ops->readpage(file, page);
>>+	if (retval < 0)
>>+		goto out;
>>+
>>+	mutex_lock(&kprobe_mutex);
>>+	hlist_for_each_entry(uprobe, node, &umodule->ulist_head, ulist)
>>+		insert_readpage_uprobe(page, mapping, uprobe);
Do all uprobe of the uprobe_module have to be inserted to the page?


>>+	mutex_unlock(&kprobe_mutex);
>>+
>>+out:
>>+	mutex_unlock(&uprobe_mutex);
>>+
>>+	return retval;
>>+}
>>+
>>+/**
>>+ * Gets exclusive write access to the given inode to ensure that the file
>>+ * on which probes are currently applied does not change. Use the function,
>>+ * deny_write_access_to_inode() we added in fs/namei.c.
>>+ */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]