]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - lib/bug.c
udp: consistently apply ufo or fragmentation
[karo-tx-linux.git] / lib / bug.c
index 06edbbef062322f12662f95d726b2d83856ac62c..a6a1137d06db75f94d005a9e646e061847be1c93 100644 (file)
--- a/lib/bug.c
+++ b/lib/bug.c
@@ -47,7 +47,7 @@
 #include <linux/sched.h>
 #include <linux/rculist.h>
 
-extern const struct bug_entry __start___bug_table[], __stop___bug_table[];
+extern struct bug_entry __start___bug_table[], __stop___bug_table[];
 
 static inline unsigned long bug_addr(const struct bug_entry *bug)
 {
@@ -62,10 +62,10 @@ static inline unsigned long bug_addr(const struct bug_entry *bug)
 /* Updates are protected by module mutex */
 static LIST_HEAD(module_bug_list);
 
-static const struct bug_entry *module_find_bug(unsigned long bugaddr)
+static struct bug_entry *module_find_bug(unsigned long bugaddr)
 {
        struct module *mod;
-       const struct bug_entry *bug = NULL;
+       struct bug_entry *bug = NULL;
 
        rcu_read_lock_sched();
        list_for_each_entry_rcu(mod, &module_bug_list, bug_list) {
@@ -122,15 +122,15 @@ void module_bug_cleanup(struct module *mod)
 
 #else
 
-static inline const struct bug_entry *module_find_bug(unsigned long bugaddr)
+static inline struct bug_entry *module_find_bug(unsigned long bugaddr)
 {
        return NULL;
 }
 #endif
 
-const struct bug_entry *find_bug(unsigned long bugaddr)
+struct bug_entry *find_bug(unsigned long bugaddr)
 {
-       const struct bug_entry *bug;
+       struct bug_entry *bug;
 
        for (bug = __start___bug_table; bug < __stop___bug_table; ++bug)
                if (bugaddr == bug_addr(bug))
@@ -141,9 +141,9 @@ const struct bug_entry *find_bug(unsigned long bugaddr)
 
 enum bug_trap_type report_bug(unsigned long bugaddr, struct pt_regs *regs)
 {
-       const struct bug_entry *bug;
+       struct bug_entry *bug;
        const char *file;
-       unsigned line, warning;
+       unsigned line, warning, once, done;
 
        if (!is_valid_bugaddr(bugaddr))
                return BUG_TRAP_TYPE_NONE;
@@ -164,6 +164,18 @@ enum bug_trap_type report_bug(unsigned long bugaddr, struct pt_regs *regs)
                line = bug->line;
 #endif
                warning = (bug->flags & BUGFLAG_WARNING) != 0;
+               once = (bug->flags & BUGFLAG_ONCE) != 0;
+               done = (bug->flags & BUGFLAG_DONE) != 0;
+
+               if (warning && once) {
+                       if (done)
+                               return BUG_TRAP_TYPE_WARN;
+
+                       /*
+                        * Since this is the only store, concurrency is not an issue.
+                        */
+                       bug->flags |= BUGFLAG_DONE;
+               }
        }
 
        if (warning) {