Intel VTune on Linux 3.9 workaround for hlist_for_each_entry

Recently I was installing Intel’s VTune on a machine with Linux 3.9. When I tried to install the sepdk driver for profiling, it failed to compile task_map.c with several errors similar to

error: macro "hlist_for_each_entry" passed 4 arguments, but takes just 3

The problem here is caused by a change to the kernel API in commit b67bfe0d42cac56c512dd5da4b1b347a23f4b70a, “hlist: drop the node parameter from iterators”.

The workaround to fix the sepdk driver on 3.9 is to edit task_map.c and remove an extra parameter from the hlist_for_each_entry calls like so:

--- task_map.c  2013-07-07 22:58:15.568356244 -0400
+++ task_map_fixed.c    2013-07-08 13:55:04.781127219 -0400
@@ -60,13 +60,12 @@
 {
     unsigned long flags;
     struct hlist_head *head;
-    struct hlist_node *node;
     vtss_task_map_item_t *item;
     if (atomic_read(&vtss_map_initialized)==0)return NULL;

     read_lock_irqsave(&vtss_task_map_lock, flags);
     head = &vtss_task_map_hash_table[vtss_task_map_hash(key)];
-    hlist_for_each_entry(item, node, head, hlist) {
+    hlist_for_each_entry(item, head, hlist) {
         if (key == item->key) {
             atomic_inc(&item->usage);
             read_unlock_irqrestore(&vtss_task_map_lock, flags);
@@ -115,13 +114,12 @@
 {
     unsigned long flags;
     struct hlist_head *head;
-    struct hlist_node *node;
     vtss_task_map_item_t *item = NULL;

     if ((item2 != NULL) && !item2->in_list) {
         write_lock_irqsave(&vtss_task_map_lock, flags);
         head = &vtss_task_map_hash_table[vtss_task_map_hash(item2->key)];
-        hlist_for_each_entry(item, node, head, hlist) {
+        hlist_for_each_entry(item, head, hlist) {
             if (item2->key == item->key) {
                 /* Already there, remove it */
                 hlist_del_init(&item->hlist);
@@ -196,7 +194,6 @@
     int i;
     unsigned long flags;
     struct hlist_head *head;
-    struct hlist_node *node;
     vtss_task_map_item_t *item;

     if (func == NULL) {
@@ -206,7 +203,7 @@
     read_lock_irqsave(&vtss_task_map_lock, flags);
     for (i = 0; i < HASH_TABLE_SIZE; i++) {
         head = &vtss_task_map_hash_table[i];
-        hlist_for_each_entry(item, node, head, hlist) {
+        hlist_for_each_entry(item, head, hlist) {
             func(item, args);
         }
     }
@@ -239,14 +236,14 @@
     int i;
     unsigned long flags;
     struct hlist_head *head;
-    struct hlist_node *node, *temp;
+    struct hlist_node *temp;
     vtss_task_map_item_t *item;

     atomic_set(&vtss_map_initialized,0);
     write_lock_irqsave(&vtss_task_map_lock, flags);
     for (i = 0; i < HASH_TABLE_SIZE; i++) {
         head = &vtss_task_map_hash_table[i];
-        hlist_for_each_entry_safe(item, node, temp, head, hlist) {
+        hlist_for_each_entry_safe(item, temp, head, hlist) {
             hlist_del_init(&item->hlist);
             item->in_list = 0;
             if (atomic_dec_and_test(&item->usage)) {

Posted July 7, 2013 under linux.