int osc_object_is_contended(struct osc_object *obj) { struct osc_device *dev = lu2osc_dev(obj->oo_cl.co_lu.lo_dev); int osc_contention_time = dev->od_contention_time; unsigned long cur_time = cfs_time_current(); unsigned long retry_time; if (OBD_FAIL_CHECK(OBD_FAIL_OSC_OBJECT_CONTENTION)) return 1; if (!obj->oo_contended) return 0; /* * I like copy-paste. the code is copied from * ll_file_is_contended. */ retry_time = cfs_time_add(obj->oo_contention_time, cfs_time_seconds(osc_contention_time)); if (cfs_time_after(cur_time, retry_time)) { osc_object_clear_contended(obj); return 0; } return 1; }
/** * Callback handler for receiving incoming glimpse ASTs. * * This only can happen on client side. After handling the glimpse AST * we also consider dropping the lock here if it is unused locally for a * long time. */ static void ldlm_handle_gl_callback(struct ptlrpc_request *req, struct ldlm_namespace *ns, struct ldlm_request *dlm_req, struct ldlm_lock *lock) { int rc = -ENOSYS; LDLM_DEBUG(lock, "client glimpse AST callback handler"); if (lock->l_glimpse_ast != NULL) rc = lock->l_glimpse_ast(lock, req); if (req->rq_repmsg != NULL) { ptlrpc_reply(req); } else { req->rq_status = rc; ptlrpc_error(req); } lock_res_and_lock(lock); if (lock->l_granted_mode == LCK_PW && !lock->l_readers && !lock->l_writers && cfs_time_after(cfs_time_current(), cfs_time_add(lock->l_last_used, cfs_time_seconds(10)))) { unlock_res_and_lock(lock); if (ldlm_bl_to_thread_lock(ns, NULL, lock)) ldlm_handle_bl_callback(ns, NULL, lock); return; } unlock_res_and_lock(lock); LDLM_LOCK_RELEASE(lock); }
int libcfs_debug_vmsg2(cfs_debug_limit_state_t *cdls, int subsys, int mask, const char *file, const char *fn, const int line, const char *format1, va_list args, const char *format2, ...) { struct cfs_trace_cpu_data *tcd = NULL; struct ptldebug_header header = {0}; struct cfs_trace_page *tage; /* string_buf is used only if tcd != NULL, and is always set then */ char *string_buf = NULL; char *debug_buf; int known_size; int needed = 85; /* average message length */ int max_nob; va_list ap; int depth; int i; int remain; if (strchr(file, '/')) file = strrchr(file, '/') + 1; tcd = cfs_trace_get_tcd(); /* cfs_trace_get_tcd() grabs a lock, which disables preemption and * pins us to a particular CPU. This avoids an smp_processor_id() * warning on Linux when debugging is enabled. */ cfs_set_ptldebug_header(&header, subsys, mask, line, CDEBUG_STACK()); if (tcd == NULL) /* arch may not log in IRQ context */ goto console; if (tcd->tcd_cur_pages == 0) header.ph_flags |= PH_FLAG_FIRST_RECORD; if (tcd->tcd_shutting_down) { cfs_trace_put_tcd(tcd); tcd = NULL; goto console; } depth = __current_nesting_level(); known_size = strlen(file) + 1 + depth; if (fn) known_size += strlen(fn) + 1; if (libcfs_debug_binary) known_size += sizeof(header); /*/ * '2' used because vsnprintf return real size required for output * _without_ terminating NULL. * if needed is to small for this format. */ for (i = 0; i < 2; i++) { tage = cfs_trace_get_tage(tcd, needed + known_size + 1); if (tage == NULL) { if (needed + known_size > CFS_PAGE_SIZE) mask |= D_ERROR; cfs_trace_put_tcd(tcd); tcd = NULL; goto console; } string_buf = (char *)cfs_page_address(tage->page) + tage->used + known_size; max_nob = CFS_PAGE_SIZE - tage->used - known_size; if (max_nob <= 0) { printk(CFS_KERN_EMERG "negative max_nob: %d\n", max_nob); mask |= D_ERROR; cfs_trace_put_tcd(tcd); tcd = NULL; goto console; } needed = 0; if (format1) { va_copy(ap, args); needed = vsnprintf(string_buf, max_nob, format1, ap); va_end(ap); } if (format2) { remain = max_nob - needed; if (remain < 0) remain = 0; va_start(ap, format2); needed += vsnprintf(string_buf + needed, remain, format2, ap); va_end(ap); } if (needed < max_nob) /* well. printing ok.. */ break; } if (*(string_buf+needed-1) != '\n') printk(CFS_KERN_INFO "format at %s:%d:%s doesn't end in newline\n", file, line, fn); header.ph_len = known_size + needed; debug_buf = (char *)cfs_page_address(tage->page) + tage->used; if (libcfs_debug_binary) { memcpy(debug_buf, &header, sizeof(header)); tage->used += sizeof(header); debug_buf += sizeof(header); } /* indent message according to the nesting level */ while (depth-- > 0) { *(debug_buf++) = '.'; ++ tage->used; } strcpy(debug_buf, file); tage->used += strlen(file) + 1; debug_buf += strlen(file) + 1; if (fn) { strcpy(debug_buf, fn); tage->used += strlen(fn) + 1; debug_buf += strlen(fn) + 1; } __LASSERT(debug_buf == string_buf); tage->used += needed; __LASSERT (tage->used <= CFS_PAGE_SIZE); console: if ((mask & libcfs_printk) == 0) { /* no console output requested */ if (tcd != NULL) cfs_trace_put_tcd(tcd); return 1; } if (cdls != NULL) { if (libcfs_console_ratelimit && cdls->cdls_next != 0 && /* not first time ever */ !cfs_time_after(cfs_time_current(), cdls->cdls_next)) { /* skipping a console message */ cdls->cdls_count++; if (tcd != NULL) cfs_trace_put_tcd(tcd); return 1; } if (cfs_time_after(cfs_time_current(), cdls->cdls_next + libcfs_console_max_delay + cfs_time_seconds(10))) { /* last timeout was a long time ago */ cdls->cdls_delay /= libcfs_console_backoff * 4; } else { cdls->cdls_delay *= libcfs_console_backoff; if (cdls->cdls_delay < libcfs_console_min_delay) cdls->cdls_delay = libcfs_console_min_delay; else if (cdls->cdls_delay > libcfs_console_max_delay) cdls->cdls_delay = libcfs_console_max_delay; } /* ensure cdls_next is never zero after it's been seen */ cdls->cdls_next = (cfs_time_current() + cdls->cdls_delay) | 1; } if (tcd != NULL) { cfs_print_to_console(&header, mask, string_buf, needed, file, fn); cfs_trace_put_tcd(tcd); } else { string_buf = cfs_trace_get_console_buffer(); needed = 0; if (format1 != NULL) { va_copy(ap, args); needed = vsnprintf(string_buf, CFS_TRACE_CONSOLE_BUFFER_SIZE, format1, ap); va_end(ap); } if (format2 != NULL) { remain = CFS_TRACE_CONSOLE_BUFFER_SIZE - needed; if (remain > 0) { va_start(ap, format2); needed += vsnprintf(string_buf+needed, remain, format2, ap); va_end(ap); } } cfs_print_to_console(&header, mask, string_buf, needed, file, fn); cfs_trace_put_console_buffer(string_buf); } if (cdls != NULL && cdls->cdls_count != 0) { string_buf = cfs_trace_get_console_buffer(); needed = snprintf(string_buf, CFS_TRACE_CONSOLE_BUFFER_SIZE, "Skipped %d previous similar message%s\n", cdls->cdls_count, (cdls->cdls_count > 1) ? "s" : ""); cfs_print_to_console(&header, mask, string_buf, needed, file, fn); cfs_trace_put_console_buffer(string_buf); cdls->cdls_count = 0; } return 0; }